繁体   English   中英

如何设置“动态”变量值?

[英]How to set “dynamically” variable values?

我在 Rails 3.0.9 上使用 Ruby 并尝试“动态”设置一些变量值。 那是...

...在我的 model 文件中,我有:

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

如何将这些变量值设置为true


我尝试使用self.send(...)方法,但我没有成功(但是,可能我根本不知道如何使用该send方法......是否可以通过使用send方法?。)。

attr_accessor :variable1, :variable2, :variable3

def set_variables(*attributes)
  attributes.each {|attribute| self.send("#{attribute}=", true)}
end

这是sendinstance_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

时间是:

      user     system      total        real
send                   1.000000   0.020000   1.020000 (  1.025247)
instance_variable_set  0.370000   0.000000   0.370000 (  0.377150)

(使用 1.9.2 测量)

应该注意的是,仅在某些情况下(例如,使用attr_accessor定义访问器) sendinstance_variable_set在功能上是等效的。 如果所涉及的访问器中存在某些逻辑,则会有所不同,您必须决定需要两者中的哪个变体。 instance_variable_set只是设置 ivar,而send实际上执行访问器方法,无论它做什么。

另一个说明 - 这两种方法在另一个方面表现不同:如果您instance_variable_set一个尚不存在的 ivar,它将被创建。 如果您使用send调用不存在的访问器,则会引发异常。

你所追求的方法是instance_variable_set所以在你的情况下:

def set_variables(*attributes)
  attributes.each {|attribute| self.instance_variable_set(attribute, true)}
end
def set_attributes(*attributes)
  attributes.each do |attr|
    self.send "#{attr}=", true
  end
end

请记住,在 Ruby 中,setter 方法名称以=结尾。

我知道这个问题是针对 Rails 3 的,但是在搜索 Rails 4 关于“如何动态访问变量值”的答案时出现了这个问题。 我在我的 model 上对此进行了测试,它可以很好地替代建议的解决方案:

def set_variables(*attributes)
  attributes.each {|attribute| self["#{attribute}"] = true}
end

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM