How to set "dynamically" variable values? How to set "dynamically" variable values? ruby ruby

How to set "dynamically" variable values?


attr_accessor :variable1, :variable2, :variable3def 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)  endendtest = Test.newBenchmark.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  endend

And the timings are:

      user     system      total        realsend                   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.


The method you're after is instance_variable_set so in your case:

def set_variables(*attributes)  attributes.each {|attribute| self.instance_variable_set(attribute, true)}end