问题
Sorry for the poor title, I don't really know what to call this.
I have something like this in Ruby:
class Test
def initialize
@my_array = []
end
attr_accessor :my_array
end
test = Test.new
test.my_array << "Hello, World!"
For the @my_array
instance variable, I want to override the <<
operator so that I can first process whatever is being inserted to it. I've tried @my_array.<<(value)
as a method in the class, but it didn't work.
回答1:
I think you're looking for this:
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
There's a good article about this and related topics at Understanding Ruby Singleton Classes.
回答2:
I'm not sure that's actually something you can do directly.
You can try creating a derived class from Array
, implementing your functionality, like:
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
回答3:
Here you go...
$ 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!"]
$
回答4:
a = []
a.instance_eval("alias old_add <<; def << value; puts value; old_add(value); end")
Very hackish, and off the top of my head ...
Just change 'puts value' with whatever preprocessing you want to do.
回答5:
You can extend the metaclass of any individual object, without having to create a whole new class:
>> i = []
=> []
>> class << i
>> def <<(obj)
>> puts "Adding "+obj.to_s
>> super
>> end
>> end
=> nil
>> i << "foo"
Adding foo
=> ["foo"]
回答6:
i extend the class, creating a method which provides access to the instance variable.
class KeywordBid
def override_ignore_price(ignore_price)
@ignorePrice = ignore_price
end
end
来源:https://stackoverflow.com/questions/1656090/overriding-instance-variable-arrays-operators-in-ruby