Overriding instance variable array's operators in Ruby

北城以北 提交于 2019-12-21 05:47:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!