-1

I know we can eval a string to get an existing variable like this:

foo = "foo"
bar = "bar"
%w{foo bar}.each do |baz|
  puts eval(baz)
end
=> "foo", "bar"

But is it possible to do the opposite, like this?

%w{foo bar}.each do |baz|
  eval(baz) = baz
end

I know a hash would work for the purpose, but hash feels like an overkill for just a couple of variables. Is there a better way to do this besides creating instance variables?

marwei
  • 29
  • 4
  • 1
    Hey @marwei , check out this post: http://stackoverflow.com/questions/18552891/how-to-dynamically-create-a-local-variable – philip yoo Feb 07 '16 at 00:05
  • If using even a hash is an overkill, then introducing something fancy with the loop is even more overkill. – sawa Feb 07 '16 at 00:43

2 Answers2

0

You could do it with instance variables like this:

%w{foo bar}.each do |baz|
  instance_variable_set "@#{baz}", baz
end

puts @foo
puts @bar

Looks like you can't do it with local variables though.

Jon
  • 10,678
  • 2
  • 36
  • 48
  • Thanks for the answer. I'm aware of the instance_variable_set method. But is there a way to just create a local variable? And I don't think the %w{foo bar}.each do |baz| eval "#{baz} = #{baz}" end works... – marwei Feb 06 '16 at 23:53
  • 1
    Since v1.9 it has not been possible to create local variables dynamically. Before that you could do it with `eval`. – Cary Swoveland Feb 07 '16 at 04:04
  • I think even before 1.9 you couldn't create new local variables with eval, but you could write to existing variables that had already been defined outside of your `eval` statement. – Jon Feb 08 '16 at 10:03
0

If I'm guessing right, you are wanting to take a string and use it as a setter.

%w{foo bar}.each do |baz|
  send("#{baz}=", baz)
end

I should have paid more attention to the title of the question. If you really want to set the variable directly, the original answer is correct.

%w{foo bar}.each do |baz|
  instance_variable_set("@#{baz}", baz)
end
james2m
  • 1,562
  • 12
  • 15