Ruby:将字符串插入到变量名称

时间:2017-05-22 15:47:04

标签: ruby-on-rails ruby ruby-on-rails-4

在Ruby中,如何插入字符串以生成变量名?

我希望能够像这样设置一个变量:

"post_#{id}" = true

这会返回一个语法错误,足够有趣:

syntax error, unexpected '=', expecting keyword_end

2 个答案:

答案 0 :(得分:4)

我相信你可以这样做:

  send("post_#{id}=", true)

当然,这需要你有适当的setter / getter。其中,因为你动态地这样做,你可能不会这样做。

所以,也许你可以这样做:

  instance_variable_set("@post_#{id}",true)

检索变量:

  instance_variable_get("@post_#{id}")
顺便说一句,如果你厌倦了输入instance_variable_set("@post_#{id}",true),只是为了好玩,你可以做类似的事情:

class Foo

  def dynamic_accessor(name) 
    class_eval do 
      define_method "#{name}" do
        instance_variable_get("@#{name}")
      end
      define_method "#{name}=" do |val|
        instance_variable_set("@#{name}",val)
      end
    end
  end

end

在这种情况下你可以:

2.3.1 :017 > id = 2
 => 2 
2.3.1 :018 > f = Foo.new
 => #<Foo:0x00000005436f20> 
2.3.1 :019 > f.dynamic_accessor("post_#{id}")
 => :post_2= 
2.3.1 :020 > f.send("post_#{id}=", true)
 => true 
2.3.1 :021 > f.send("post_#{id}")
 => true 
2.3.1 :022 > f.send("post_#{id}=", "bar")
 => "bar" 
2.3.1 :023 > f.send("post_#{id}")
 => "bar" 

答案 1 :(得分:0)

这涉及获取和设置局部变量。假设

id = 1
s = "post_#{id}"
  #=> "post_1"

从Ruby v1.8开始,无法动态创建局部变量。因此,如果本地变量post_1不存在,则可以使用 方式创建它,方法是使用赋值语句:

post_1 = false

如果存在局部变量post_1,则可以使用

动态检索其值
b = binding
b.local_variable_get(s)
  #=> false

(或b.local_variable_get(s.to_sym))并使用

动态设置其值
b.local_variable_set(s, true)
  #=> true
post_1
  #=> true

(或b.local_variable_set(s.to_sym, true))。

请参阅Binding#local_variable_getBinding#local_variable_set