我有这段代码:
class Test
attr_accessor :test_attr
def initialize
@test_attr = ""
end
def test_attr_changed
p 'test_attr is changed: ' + @test_attr
end
end
当我更改属性:test_attr
时:
test = Test.new
test.test_attr = "New value"
我希望它触发test_attr_changed
功能并输出:
test_attr is changed: New value
有没有办法在Ruby中像QML onChanged
信号那样做?
答案 0 :(得分:3)
这是一个如何模块化这个功能的相当简单的实现
module Overlord
module ClassMethods
def attr_watcher(*attrs)
attrs.each do |attr|
define_method(attr) {instance_variable_get("@#{attr}")}
define_method("#{attr}=") do |val|
changes[attr] << {new: val, old: send(attr), when: Time.now}
instance_variable_set("@#{attr}",val)
end
end
end
end
def self.included(base)
base.extend(ClassMethods)
end
def changes
@changes ||= Hash.new {|h,k| h[k] = []}
end
end
class Test
include Overlord
attr_watcher :name
end
然后简单地
t = Test.new
t.changes
#=> {}
t.name = "Mnky"
t.changes
#=> => {:name=>[{:new=>"Mnky", :old=>nil, :when=>2017-08-24 11:17:27 -0400}]}
t.name = "Other"
t.changes[:name]
#=> [
{:new=>"Mnky", :old=>nil, :when=>2017-08-24 11:17:27 -0400},
{:new=>"Other", :old=>"Mnky", :when=>2017-08-24 11:17:58 -0400}]
t.name
#=> "Other"
答案 1 :(得分:2)
删除attr_accessor :test_attr
。
class Test
attr_reader :test_attr
def test_attr=(value)
@test_attr = value
test_attr_changed
value
end
end