1

I'm trying to generate a bunch of variables that will be operated on. Started with 2 variables, 4, 8,16 and its about time I put the variable generation in a loop.

The variable is acting as a storage for the index of an array.

So a thread wakes up, picks up a variable and says "variable_0" is the first index, and stores location 24 inside of it.

This is usually done like so. This variable goes on and is used multiple times later on.

variable_0 = get_index(threadid)

Once I have 16 of such variables, its a pain and ugly to see that line repeated more than once. So I thought I'd put in a loop and tried it with 2 methods.

1. EVAL

for i in 0..15 do 
    eval("variable_#{i} = get_index(threadid)")
end

Does not work at all.

2. instance_variable_set

for i in 0..15 do
    index_name = "variable_#{i}"
    index_val = get_index(threadid)
    instance_variable_set("#{index_name}", :index_val)
end

This doesn't work either, since a later statement prints "variable not found " pretty much.

Is there a good way to go about doing this?

Due to restrictions later down the line, I cannot use an array for this, each variable has to be constructed as a single variable, so no arrays or anything like that would work

7
  • 2
    This is a common XY-problem asked repeatedly. You should use an array to keep all the values. Commented Feb 24, 2016 at 16:23
  • Variables are used by external software, it doesn't take in array elements. I mean I wrote this above as well, its a limitation I can't overcome, its not my own unwillingness to work with arrays.... Commented Feb 24, 2016 at 16:26
  • But you seem to have freedom with variable naming (local or instance). It is a strange situation that you nevertheless do not have freedom of using an array. Your situation is not clear. Commented Feb 24, 2016 at 16:28
  • 1
    Can I ask why you want to have a set of variables containing a counter instead of just an array? Why is @variable_0 better than @variables[0]? Commented Feb 24, 2016 at 16:34
  • 2
    @JohnNikolaou that doesn't make much sense. You are passing the object that is assigned to the variable, not the variable itself. Therefore, it is irrelevant if the object is assigned to a variable or element of an array. Commented Feb 24, 2016 at 16:42

2 Answers 2

3

As others have pointed out it is not possible to create local variables dynamically in Ruby, you could set up a binding as well if you're looking for another method of achieving this.

With eval

b = binding
10.times do |i|
  eval("var#{i} = 'foo'", b)
end

> eval("var1", b)
=> "foo"

> eval("local_variables", b)
=> [:var9, :var8, :var7, :var6, :var5, :var4, :var3, :var2, :var1, :var0, :b, :_]

Without eval

b = binding
10.times do |i|
  b.local_variable_set("var#{i}", 'foo')
end

> b.local_variable_get('var1')
=> "foo"

> b.local_variables
=> [:var9, :var8, :var7, :var6, :var5, :var4, :var3, :var2, :var1, :var0, :b, :_]
Sign up to request clarification or add additional context in comments.

3 Comments

correct answer but not the "nice" one. I rly dont like use eval this way. but +1
Agreed eval always seems evil, however this is the way as described by ruby docs (ruby-doc.org/core-2.3.0/Binding.html)
I've updated it without eval as well, seems it was possible after all!
2

Your second example is almost valid. You forgot @ for instance variable name and you passed a symbol as value instead the value itself.

for i in 0..15 do
  index_val = "some value #{i}"
  instance_variable_set("@variable_#{i}", index_val)
end

puts @variable_4 # "some value"

https://repl.it/BnLO/6

6 Comments

This is a terrible pattern, you should have answered something that would help the OP to do better code, like creating an array of values and operation on them.
True that. But poster has expressed that Array can't be used. Who am I to judge?
You don't need the colon in :"@variable_#{i}". The method accepts strings as well as symbols.
Thank you @sawa, corrected.
@jturolla Yes, this is terrible pattern, but he ask a question and this is correct answer. Ofc, better way is to use Hash or Array.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.