在Ruby和作用域中覆盖实例变量数组的运算符

时间:2010-07-22 11:41:59

标签: ruby arrays singleton

我有一个测试类和一个box类,在测试类中我有一个名为boxHolder的var,它是一个数组,我想覆盖<<这个数组的方法。在单身人士里面如何访问moski_call?

class Test
  attr_accessor :boxHolder

  def initialize()
   super
   self.boxHolder = 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 

3 个答案:

答案 0 :(得分:0)

怎么样:

def self.boxHolder.<< (box)
   box.setPositionWithinColumn(moski_call)
   super(box)
end     

这将为您的实例boxHolder声明一个方法。但是boxHolder无法访问方法moski_call

答案 1 :(得分:0)

像这样:

# 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)
}

答案 2 :(得分:0)

您需要保持对“父”Test对象的访问权限。这可以使用块是闭包的事实来完成:

parent = self # to be accessible in the closure

@boxHolder.define_singleton_method(:<<) do |box|
  box.setPositionWithinColumn(parent.moski_call)
  super(box)
end

注意define_singleton_method是Ruby 1.9中的新功能,因此如果使用较旧的Ruby,请升级require 'backports/1.9.1/kernel/define_singleton_method'或执行class << @boxHolder; define_method(:<<){ "..." } end