在Ruby中覆盖实例变量数组的运算符

时间:2009-11-01 01:16:13

标签: ruby operators operator-overloading

对于糟糕的头衔感到抱歉,我真的不知道该怎么称呼它。

我在Ruby中有这样的东西:

class Test
  def initialize
    @my_array = []
  end
  attr_accessor :my_array
end
test = Test.new
test.my_array << "Hello, World!"

对于@my_array实例变量,我想覆盖<<运算符,以便我可以先处理插入的内容。我已经尝试@my_array.<<(value)作为课程中的一种方法,但它没有用。

6 个答案:

答案 0 :(得分:10)

我认为你正在寻找这个:

class Test
  def initialize
    @myarray = []
    class << @myarray
      def <<(val)
        puts "adding #{val}" # or whatever it is you want to do first
        super(val)
      end
    end
  end
  attr_accessor :myarray
end

Understanding Ruby Singleton Classes上有一篇关于这个及相关主题的好文章。

答案 1 :(得分:2)

我不确定这实际上是你可以直接做的事情。

您可以尝试从Array创建派生类,实现您的功能,例如:

class MyCustomArray < Array
  def initialize &process_append
    @process_append = &process_append
  end
  def << value
    raise MyCustomArrayError unless @process_append.call value
    super.<< value
  end
end

class Test
  def initialize
    @my_array = MyCustomArray.new
  end
  attr_accessor :my_array
end

答案 2 :(得分:1)

你去......

$ cat ra1.rb

class Aa < Array
  def << a
    puts 'I HAVE THE CONTROL!!'
    super a
  end
end

class Test
  def initialize
    @my_array = Aa.new
  end
  attr_accessor :my_array
end

test = Test.new
test.my_array << "Hello, World!"
puts test.my_array.inspect
$ ruby ra1.rb
I HAVE THE CONTROL!!
["Hello, World!"]
$ 

答案 3 :(得分:0)

a = []
a.instance_eval("alias old_add <<; def << value; puts value; old_add(value); end")

非常hackish,并且脱离了我的头顶......

只需将'put value'更改为您想要执行的任何预处理。

答案 4 :(得分:0)

您可以扩展任何单个对象的元类,而无需创建一个全新的类:

>> i = []
=> []
>> class << i
>>   def <<(obj)
>>     puts "Adding "+obj.to_s
>>     super
>>   end
>> end
=> nil
>> i << "foo"
Adding foo
=> ["foo"]

答案 5 :(得分:0)

我扩展了类,创建了一个提供对实例变量的访问的方法。

        class KeywordBid
          def override_ignore_price(ignore_price)
            @ignorePrice = ignore_price
          end
        end