自定义<<方法

时间:2010-08-02 00:23:00

标签: ruby

class Foo
  def initialize
    @bar = []
  end

  def changed_callback
    puts "Bar has been changed!"
  end

  def bar
    @bar
  end

  def bar=(a)
    @bar = a
    self.changed_callback() # (hence why this doesn't just use attr_accessor)
  end

  def bar<<(a)
    @bar.push(a)
    self.changed_callback()
  end
end

f = Foo.new()
f.bar = [1,2,3]
  => "Bar has been changed!"
f.bar << 4
  => "Bar has been changed!"
puts f.bar.inspect
  => [1,2,3,4]

有可能吗?

谢谢!

1 个答案:

答案 0 :(得分:3)

您需要以某种方式使用适当的Foo#bar方法扩展#<<返回的对象。可能是这样的事情吗?

class Foo
  module ArrayProxy
    def <<(other)
      @__foo__.changed_callback
      super
    end
  end

  def initialize
    @bar = []
  end

  def changed_callback
    puts 'Bar has been changed!'
  end

  def bar
    return @bar if @bar.is_a?(ArrayProxy)
    @bar.tap {|bar| bar.extend(ArrayProxy).instance_variable_set(:@__foo__, self) }
  end

  def bar=(a)
    @bar = a
    changed_callback # (hence why this doesn't just use attr_accessor)
  end

end

f = Foo.new
f.bar = [1,2,3]
#  "Bar has been changed!"
f.bar << 4
#  "Bar has been changed!"
puts f.bar.inspect
#  => [1,2,3,4]