开发者

Custom << method

开发者 https://www.devze.com 2023-01-09 15:06 出处:网络
class Foo def initialize @bar = [] end def changed_callback puts \"Bar has been changed!\" end def bar @bar end
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&开发者_运维百科lt;<(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]

Is anything like that possible?

Thanks!


You need to somehow extend the object returned by Foo#bar with an appropriate #<< method. Something like this, maybe?

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]
0

精彩评论

暂无评论...
验证码 换一张
取 消