Ruby中的Track Array更改

时间:2016-05-13 13:06:20

标签: arrays ruby

我想知道,如果有一种简单的方法来实现类似于ActiveModel::Dirty的行为的Ruby数组,那么我可以这样做:

array = [1,2]
array.changed? # => false
array << 5
array.changed? # => true

到目前为止,我唯一的想法是实现TrackedArray < ArrayTrackedArray < DelegateClass(Array),浏览Array的公共API,为每个带有感叹号的方法调用define_method和其他一些(如{ {1}},keep_if等等)并设置<<

有了这个,我会为每个数组实例得到@changed_marker = true,它会被更改一次,但如果撤消对象上的更改,它将不会返回changed? == true。因此它与changed? == false不完全兼容。

对于笨拙的实施而言,这似乎是一项艰巨的努力......

1 个答案:

答案 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