Overriding instance variable array’s operators in Ruby and scoping
I have a test class and a box class, in the test class i have a var called boxHolder, which is an array, i want to override the << method for this array. Inside the singleton how can i access moski_call ?
class Test attr_accessor :boxHolder def initialize() super self.boxHold开发者_JAVA技巧er = Array.new class << @boxHolder def <<(box) box.setPositionWithinColumn(moski_call) super(box) end end end def moski_call "YAAAAAAAAAAAAAAAAAAAA" end end class Box def initialize end def setPositionWithinColumn(str) puts "got a string #{str}" end end # test box = Box.new test = Test.new test.boxHolder
like this:
# need this or else `moski_call` method is looked up in context of @boxholder
moski_call_output = moski_call
class << @boxholder; self; end.send(:define_method, :<<) { |box|
box.setPositionWithinColumn(moski_call_output)
super(box)
}
What about:
def self.boxHolder.<< (box)
box.setPositionWithinColumn(moski_call)
super(box)
end
This would declare a method for your instance boxHolder. But boxHolder does not have access to the method moski_call
You need to maintain access to the "parent" Test
object. This can be done using the fact that blocks are closures:
parent = self # to be accessible in the closure
@boxHolder.define_singleton_method(:<<) do |box|
box.setPositionWithinColumn(parent.moski_call)
super(box)
end
Note: define_singleton_method
is new in Ruby 1.9, so either upgrade, require 'backports/1.9.1/kernel/define_singleton_method'
or do class << @boxHolder; define_method(:<<){ "..." } end
if using an older Ruby.
精彩评论