【问题标题】:How do I force the same hash value for different object instantiations in RoR?如何为 RoR 中的不同对象实例强制使用相同的哈希值?
【发布时间】:2017-12-14 10:07:54
【问题描述】:

我正在使用 RoR 5.0.1。我有一个没有持久化到数据库的模型。它有两个字段

first_field
second_field

如何强制其字段具有相同值的对象的不同实例化具有相同的哈希值?现在似乎每个对象的唯一创建都有不同的哈希值,即使各个属性具有相同的值。所以如果我创建两个不同的对象

o1 = MyObject.new({:first_field => 5, :second_field => "a"})

o2 = MyObject.new({:first_field => 5, :second_field => "a"})

我希望它们具有相同的哈希值,即使它们是对象的不同实例。

【问题讨论】:

  • 您可以覆盖MyObject (ruby-doc.org/core-2.4.1/Object.html#method-i-hash) 的hash 方法,但这会破坏很多东西...
  • 您是否希望它们相同以便编辑一个修改另一个,或者您希望o1 == o2 成为true
  • @MichaelGorman,如果 h = {},那么我希望 h[o1] 产生与 h[o2] 相同的结果。
  • this question 的答案应该是你要找的

标签: ruby-on-rails hash ruby-on-rails-5


【解决方案1】:

您正在寻找的行为在您的问题中并不完全清楚。但是,如果您希望(正如 Michael Gorman 所要求的)MyObject 的实例共享相同的 hash 实例(这样对值 o1 的更改会反映在 o2 的值中),那么您可以这样做类似:

  class MyObject

    def initialize(hsh = {})
      @hsh = hsh
      hsh.each do |k,v|
        class_eval do

          # define the getter
          define_method(k) do 
            @hsh[k]
          end

          # define the setter
          define_method("#{k}=") do |val|
            @hsh[k] = val
          end

        end
      end
    end

  end

然后创建hash的单个实例:

  hsh = {first_field: 5, second_field: "a"}

然后用这个hash 实例化你的两个对象:

  o1 = MyObject.new(hsh)
  o2 = MyObject.new(hsh)

两个实例将具有相同的first_field 值:

  2.3.1 :030 > o1.first_field
   => 5 
  2.3.1 :031 > o2.first_field
   => 5 

o1.first_field 的变化将反映在o2.first_field

  2.3.1 :033 > o1.first_field = 7
   => 7 
  2.3.1 :034 > o1.first_field
   => 7 
  2.3.1 :035 > o2.first_field
   => 7 

second_field相同:

  2.3.1 :037 > o1.second_field
   => "a" 
  2.3.1 :038 > o2.second_field
   => "a" 

  2.3.1 :040 > o1.second_field = "b"
   => "b" 
  2.3.1 :041 > o1.second_field
   => "b" 
  2.3.1 :042 > o2.second_field
   => "b" 

由于settergetter 是动态生成的,您可以执行以下操作:

  hsh = {first_field: 5, second_field: "a", nth_field: {foo: :bar}}
  o1 = MyObject.new(hsh)

o1 将响应nth_field 而无需对MyObject 进行任何额外编码:

  2.3.1 :048 > o1.nth_field
   => {:foo=>:bar}

【讨论】:

  • 为了澄清我想要的,从你的例子中,如果我设置 hsh[o1] = 3,那么我希望 hash[o2] 产生 3,假设 o1.first_field == o2.first_field 和 o1 .second_field == o2.second_field。这有意义吗?
  • 我假设您的意思是,“如果我设置 *hash*[o1] = 3,那么我希望 hash[o2] 产生 3”。我对你到底想做什么还是有点模糊。但是,在我看来,您的要求不太适合 Hash
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-28
  • 2014-05-06
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多