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