Ruby:是否可以设置实例变量的值,其中实例变量通过字符串命名?

时间:2010-12-06 19:20:27

标签: ruby

不确定调用此模式的是什么,但这里是场景:

class Some
   #this class has instance variables called @thing_1, @thing_2 etc.
end

有没有办法设置实例变量的值,其中实例变量名是由字符串创建的?

类似的东西:

i=2
some.('thing_'+i) = 55 #sets the value of some.thing_2 to 55

3 个答案:

答案 0 :(得分:17)

Object上搜索“instance_variable”:

some.instance_variable_get(("@thing_%d" % 2).to_sym)
some.instance_variable_set(:@thing_2, 55)

这种模式被称为“爱抚”;如果您要计算这样的密钥,那么显式使用哈希或数组会更好。

答案 1 :(得分:2)

您可以为这些实例变量生成访问器方法,然后只生成send setter:

class Stuff
  attr_accessor :thing_1, :thing_2
end

i = 1
s = Stuff.new
s.send("thing_#{i}=", :bar)
s.thing_1 # should return :bar

答案 2 :(得分:0)

我想知道同样的事情,所以我一直在玩控制台。 有趣的东西:

class Parent
  class << self
    attr_accessor :something

    def something(value = nil)
      @something = value ? value : @something
    end

    def inherited(subclass)
      self.instance_variables.each do |var|
        subclass.instance_variable_set(var, self.instance_variable_get(var))
      end
    end
  end

  attr_accessor :something
  self.something = 'Parent Default'

  def something(value = nil)
    @something = value ? value : @something ? @something : self.class.something
  end
end

class Child < Parent
  # inherited form Parent.something
end

class GrandChild < Child
  something "GrandChild default"
end

结果:

Parent.something
# => "Parent Default" 
Parent.something = "Parent something else"
# => "Parent something else" 
Parent.something
# => "Parent something else" 
parent = Parent.new
# => #<Parent:0x007fc593474900> 
parent.something
# => "Parent something else" 
parent.something = "yet something different"
# => "yet something different" 
parent.something
# => "yet something different" 
parent.class.something
# => "Parent something else" 
Child.something
# => "Parent Default" 
child = Child.new
# => #<Child:0x007fc5934241f8> 
child.something
# => "Parent Default" 
GrandChild.something
# => "GrandChild default" 
GrandChild.something("grandchild something else") 
# => "grandchild something else" 
GrandChild.something
# => "grandchild something else" 
GrandChild.superclass.something
# => "Parent Default" 
grandchild = GrandChild.new
# => #<GrandChild:0x007fc5933e70c8> 
grandchild.something
# => "grandchild something else" 
grandchild.something = "whatever"
# => "whatever" 
GrandChild.something
# => "grandchild something else" 
grandchild.something
# => "whatever"