加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

属性更改时更新Ruby类属性哈希

发布时间:2020-12-17 03:26:27 所属栏目:百科 来源:网络整理
导读:我正在尝试编写一个类似于Rails AactiveRecord模型的 Ruby类,其处理方式是: class Person attr_accessor :name,:age # init with Person.new(:name = 'John',:age = 30) def initialize(attributes={}) attributes.each { |key,val| send("#{key}=",val) if
我正在尝试编写一个类似于Rails AactiveRecord模型的 Ruby类,其处理方式是:

class Person
  attr_accessor :name,:age

  # init with Person.new(:name => 'John',:age => 30)
  def initialize(attributes={})
    attributes.each { |key,val| send("#{key}=",val) if respond_to?("#{key}=") }
    @attributes = attributes
  end

  # read attributes
  def attributes
    @attributes
  end

  # update attributes
  def attributes=(attributes)
    attributes.each do |key,val| 
      if respond_to?("#{key}=")
        send("#{key}=",val) 
        @attributes[key] = name
      end
    end
  end
end

我的意思是,当我初始化类时,使用相关属性更新“属性”哈希:

>>> p = Person.new(:name => 'John',:age => 30)
>>> p.attributes
 => {:age=>30,:name=>"John"}
>>> p.attributes = { :name => 'charles' }
>>> p.attributes
 => {:age=>30,:name=>"charles"}

到现在为止还挺好.我想要发生的是在设置单个属性时更新属性哈希:

>>> p.attributes
 => {:age=>30,:name=>"John"}
>>> p.name
 => "John"
>>> p.name = 'charles' # <--- update an individual property
 => "charles"
>>> p.attributes
 => {:age=>30,:name=>"John"} # <--- should be {:age=>30,:name=>"charles"}

我可以通过为每个属性编写一个setter和getter而不是使用attr_accessor来做到这一点,但这会让一个有很多字段的模型很糟糕.有什么快速的方法来完成这个

解决方法

问题是您将属性保存为单独的ivars,并保存在@attributes哈希中.您应该只选择和使用一种方式.

如果你想使用一个哈希,你应该自己创建一个访问器,这会将它们“重新路由”到一个可以设置和获取哈希的方法:

class Class  
 def my_attr_accessor(*accessors)
   accessors.each do |m|

     define_method(m) do  
       @attributes[m]
     end        

     define_method("#{m}=") do |val| 
       @attributes[m]=val
     end
   end
 end
end

class Foo
  my_attr_accessor :foo,:bar

  def initialize
    @attributes = {}
  end
end

foo = Foo.new

foo.foo = 123
foo.bar = 'qwe'
p foo
#=> #<Foo:0x1f855c @attributes={:foo=>123,:bar=>"qwe"}>

如果你想使用ivars,你应该再次推出自己的attr_accessor方法,此方法还要记住哪些ivars应该是“attributes”,并在attributes方法中使用该列表.而属性方法会在运行中创建一个哈希值并返回它.

Here你可以找到一篇关于实现访问器的好文章.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读