我想知道,如果有一种简单的方法来实现类似于ActiveModel::Dirty
的行为的Ruby数组,那么我可以这样做:
array = [1,2]
array.changed? # => false
array << 5
array.changed? # => true
到目前为止,我唯一的想法是实现TrackedArray < Array
或TrackedArray < DelegateClass(Array)
,浏览Array的公共API,为每个带有感叹号的方法调用define_method
和其他一些(如{ {1}},keep_if
等等)并设置<<
。
有了这个,我会为每个数组实例得到@changed_marker = true
,它会被更改一次,但如果撤消对象上的更改,它将不会返回changed? == true
。因此它与changed? == false
不完全兼容。
对于笨拙的实施而言,这似乎是一项艰巨的努力......
答案 0 :(得分:1)
天真的实施(出于好奇):
class Hurray
attr_accessor :dirty
def initialize *args, &cb
@array = Array.new *args, &cb
@dirty = false
end
def method_missing m, *args, &cb
@dup = @array.dup
# maybe public_send, maybe whitelist methods
@array.send(m, *args, &cb).tap do
@dirty |= @dup != @array
end
end
end
有人可能会attr_reader :dup
在修改数组之前访问该数组的最后一个副本,例如undo
。