In Ruby, how can I interpolate a string to make a variable name?
I want to be able to set a variable like so:
"post_#{id}" = true
This returns a syntax error, funnily enough:
syntax error, unexpected '=', expecting keyword_end
In Ruby, how can I interpolate a string to make a variable name?
I want to be able to set a variable like so:
"post_#{id}" = true
This returns a syntax error, funnily enough:
syntax error, unexpected '=', expecting keyword_end
I believe you can do something like:
send("post_#{id}=", true)
That would require, of course, that you have appropriate setter/getter. Which, since you're doing this dynamically, you probably don't.
So, perhaps you could do:
instance_variable_set("@post_#{id}",true)
To retrieve the variable:
instance_variable_get("@post_#{id}")
BTW, if you get tired of typing instance_variable_set("@post_#{id}",true)
, just for fun you could do something like:
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
In which case you could:
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"
This concerns the getting and setting of local variables. Suppose
id = 1
s = "post_#{id}"
#=> "post_1"
Since Ruby v1.8 it has not been possible to create local variables dynamically. Therefore, if a local variable post_1
does not exist, the only way you can create it is by using an assignment statement:
post_1 = false
If the local variable post_1
exists, you can retrieve its value dynamically with
b = binding
b.local_variable_get(s)
#=> false
(or b.local_variable_get(s.to_sym)
) and set its value dynamically with
b.local_variable_set(s, true)
#=> true
post_1
#=> true
(or b.local_variable_set(s.to_sym, true)
).
See Binding#local_variable_get and Binding#local_variable_set.