I am using Ruby on Rails 3.0.9 and I am trying to set "dynamically" some variable values. That is...
... in my model file I have:
attr_accessor :variable1, :variable2, :variable3 # The 'attributes' argument contains one or more symbols which name is equal to # one or more of the 'attr_accessor' symbols. def set_variables(*attributes) # Here I should set to 'true' all ":variable<N>" attributes passed as symbol # in the 'attributes' array, but variable names should be interpolated in a # string. # # For example, I should set something like "prefix_#{':variable1'.to_s}_suffix". end How can I set those variable values to true?
I tried to use the self.send(...) method, but I did not succeed (but, probably, I don't know how to use at all that send method... is it possible do to that I need by using the send method?!).
attr_accessor :variable1, :variable2, :variable3 def set_variables(*attributes) attributes.each {|attribute| self.send("#{attribute}=", true)} end
Here's the benchmark comparison of send vs instance_variable_set:
require 'benchmark' class Test VAR_NAME = '@foo' ATTR_NAME = :foo attr_accessor ATTR_NAME def set_by_send i send("#{ATTR_NAME}=", i) end def set_by_instance_variable_set i instance_variable_set(VAR_NAME, i) end end test = Test.new Benchmark.bm do |x| x.report('send ') do 1_000_000.times do |i| test.set_by_send i end end x.report('instance_variable_set') do 1_000_000.times do |i| test.set_by_instance_variable_set i end end end And the timings are:
user system total real send 1.000000 0.020000 1.020000 ( 1.025247) instance_variable_set 0.370000 0.000000 0.370000 ( 0.377150) (measured using 1.9.2)
It should be noted that only in certain situations (like this one, with accessor defined using attr_accessor) are send and instance_variable_set functionally equivalent. If there is some logic in the accessor involved, there would be a difference, and you would have to decide which variant you would need of the two. instance_variable_set just sets the ivar, while send actually executes the accessor method, whatever it does.
Another remark - the two methods behave differently in another aspect: if you instance_variable_set an ivar which doesn't exist yet, it will be created. If you call an accessor which doesn't exist using send, an exception would be raised.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With