# Dynamic Variables

**URL:** https://rubytalk.org/t/dynamic-variables/47446
**Category:** ruby-talk
**Created:** [1 July 2008 09:45 UTC](https://rubytalk.org/t/dynamic-variables/47446 "2008-07-01T09:45:48Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![Marc\_Heiler](https://avatars.discourse-cdn.com/v4/letter/m/e8c25b/32.png) [@Marc\_Heiler](https://rubytalk.org/u/Marc_Heiler)
#### Post date: [1 July 2008 09:45 UTC](https://rubytalk.org/t/dynamic-variables/47446/1 "2008-07-01T09:45:48Z")

</div>

Is there any way in ruby to create dynamic variables?

counter = 52  
box#{counter} = "cat and dogs"

There would be then a new variable  
box52

Note that this is not a question whether someone should do it or not -  
this is solely whether it is doable or not. Until today I thought it is  
somehow possible with eval but I failed, so I assume it is not possible.

> **···**
>
> --  
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

---

<div class="post-metadata">

### Author: ![Igal\_Koshevoy](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@Igal\_Koshevoy](https://rubytalk.org/u/Igal_Koshevoy)
#### Post date: [1 July 2008 09:52 UTC](https://rubytalk.org/t/dynamic-variables/47446/2 "2008-07-01T09:52:17Z")

</div>

Marc Heiler wrote:

> Is there any way in ruby to create dynamic variables?
> 
> counter = 52  
> box#{counter} = "cat and dogs"
> 
> There would be then a new variable  
> box52
> 
> Note that this is not a question whether someone should do it or not -  
> this is solely whether it is doable or not. Until today I thought it is  
> somehow possible with eval but I failed, so I assume it is not possible.  
> &nbsp;&nbsp;

irb(main):010:0\> counter = 52  
=\> 52  
irb(main):011:0\> eval "box#{counter} = 'cat and dogs'"  
=\> "cat and dogs"  
irb(main):012:0\> box52  
=\> "cat and dogs"

-igal

---

<div class="post-metadata">

### Author: ![\_Pena\_Botp1](https://avatars.discourse-cdn.com/v4/letter/_/94ad74/32.png) [@\_Pena\_Botp1](https://rubytalk.org/u/_Pena_Botp1)
#### Post date: [1 July 2008 10:25 UTC](https://rubytalk.org/t/dynamic-variables/47446/3 "2008-07-01T10:25:29Z")

</div>

# Is there any way in ruby to create dynamic variables?

note sure, but no. There's no need 😉

# counter = 52  
# box#{counter} = "cat and dogs"  
# There would be then a new variable box52  
# Note that this is not a question whether someone should do it or  
# not -this is solely whether it is doable or not. Until today I  
# thought it is somehow possible with eval but I failed, so I assume  
# it is not possible.

variables in ruby are just references to objects. and since ruby objects can be dynamic, variables are dynamic in a basic sense, but in an o-o way 😉

on your case, why not make box refer to a dynamic object, like a hash?

eg,

box={}  
#=\> {}  
counter = 52  
#=\> 52  
box[counter] = 'cat and dogs'  
#=\> "cat and dogs"

box[counter]  
#=\> "cat and dogs"

store anything you want,

box["myname"]="botp"  
#=\> "botp"

even store a proc and call it

box[42]=lambda{box[counter].upcase}  
#=\> #\<Proc:0x028d31e4@(irb):9\>

box  
#=\> {"myname"=\>"botp", 52=\>"cat and dogs", 42=\>#\<Proc:0x028d31e4@(irb):9\>}

box[42].call  
#=\> "CAT AND DOGS"

and you can even let box, cleanup itself 🙂

box["cleanup"]=lambda{box.clear}  
#=\> #\<Proc:0x028c141c@(irb):19\>

box["cleanup"].call  
#=\> {}

box  
#=\> {}

kind regards -botp

> **···**
>
> From: Marc Heiler [[mailto:shevegen@linuxmail.org](mailto:shevegen@linuxmail.org)]

---

<div class="post-metadata">

### Author: ![Gregory\_Seidman](https://avatars.discourse-cdn.com/v4/letter/g/eb9ed0/32.png) [@Gregory\_Seidman](https://rubytalk.org/u/Gregory_Seidman)
#### Post date: [1 July 2008 12:50 UTC](https://rubytalk.org/t/dynamic-variables/47446/4 "2008-07-01T12:50:25Z")

</div>

I'm going to give you exactly what you didn't ask for: why this is a bad  
idea. This is a discussion about Perl rather than Ruby, but it remains  
relevant: [Why it's stupid to `use a variable as a variable name'](http://perl.plover.com/varvarname.html)

See the subsequent parts of the series for further discussion.

--Greg

> **···**
>
> On Tue, Jul 01, 2008 at 06:45:48PM +0900, Marc Heiler wrote:
> 
> > Is there any way in ruby to create dynamic variables?
> > 
> > counter = 52  
> > box#{counter} = "cat and dogs"
> > 
> > There would be then a new variable  
> > box52
> > 
> > Note that this is not a question whether someone should do it or not -  
> > this is solely whether it is doable or not. Until today I thought it is  
> > somehow possible with eval but I failed, so I assume it is not possible.

---

<div class="post-metadata">

### Author: ![Martin\_Boese](https://avatars.discourse-cdn.com/v4/letter/m/35a633/32.png) [@Martin\_Boese](https://rubytalk.org/u/Martin_Boese)
#### Post date: [1 July 2008 14:16 UTC](https://rubytalk.org/t/dynamic-variables/47446/5 "2008-07-01T14:16:37Z")

</div>

'Object' has a method to define instance variables:

irb(main):001:0\> counter = 52  
irb(main):002:0\> self.instance\_variable\_set("@box#{counter}", 'cat and dogs')  
=\> "cat and dogs"  
irb(main):003:0\> @box52  
=\> "cat and dogs"

martin

> **···**
>
> On Tuesday 01 July 2008 10:45:48 Marc Heiler wrote:
> 
> > Is there any way in ruby to create dynamic variables?
> > 
> > counter = 52  
> > box#{counter} = "cat and dogs"
> > 
> > There would be then a new variable  
> > box52
> > 
> > Note that this is not a question whether someone should do it or not -  
> > this is solely whether it is doable or not. Until today I thought it is  
> > somehow possible with eval but I failed, so I assume it is not possible.

---

<div class="post-metadata">

### Author: ![Calamitas](https://avatars.discourse-cdn.com/v4/letter/c/b782af/32.png) [@Calamitas](https://rubytalk.org/u/Calamitas)
#### Post date: [1 July 2008 10:12 UTC](https://rubytalk.org/t/dynamic-variables/47446/6 "2008-07-01T10:12:01Z")

</div>

Now try the same thing in plain ruby without irb. Never trust irb on  
things like these.

Dynamic variables as created by eval live in a separate, eval-specific  
scope and can only be accessed through eval. This is a consequence of  
Ruby deciding at "compile" time what's a local variable and what's  
not. So, if you have code like this:

&nbsp;&nbsp;&nbsp;eval "a = 5"  
&nbsp;&nbsp;&nbsp;p a

then in "p a", a is determined to be a method call before that code is  
even run. The a is accessible through eval though:

&nbsp;&nbsp;eval "a = 5"  
&nbsp;&nbsp;p eval("a")

Peter

> **···**
>
> On Tue, Jul 1, 2008 at 11:52 AM, Igal Koshevoy \<igal@pragmaticraft.com\> wrote:
> 
> > Marc Heiler wrote:
> > 
> > > Is there any way in ruby to create dynamic variables?
> > > 
> > > counter = 52  
> > > box#{counter} = "cat and dogs"
> > > 
> > > There would be then a new variable  
> > > box52
> > > 
> > > Note that this is not a question whether someone should do it or not -  
> > > this is solely whether it is doable or not. Until today I thought it is  
> > > somehow possible with eval but I failed, so I assume it is not possible.
> > 
> > irb(main):010:0\> counter = 52  
> > =\> 52  
> > irb(main):011:0\> eval "box#{counter} = 'cat and dogs'"  
> > =\> "cat and dogs"  
> > irb(main):012:0\> box52  
> > =\> "cat and dogs"

---

<div class="post-metadata">

### Author: ![Frederick\_Cheung1](https://avatars.discourse-cdn.com/v4/letter/f/ecc23a/32.png) [@Frederick\_Cheung1](https://rubytalk.org/u/Frederick_Cheung1)
#### Post date: [1 July 2008 10:12 UTC](https://rubytalk.org/t/dynamic-variables/47446/7 "2008-07-01T10:12:15Z")

</div>

Although that doesn't work outside of irb. (although you can change the value of an existing local variable like that)  
See also [http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/a954f8aaf698a0b9/e1c761b71b63b82e?#e1c761b71b63b82e](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/a954f8aaf698a0b9/e1c761b71b63b82e?#e1c761b71b63b82e)

Fred

> **···**
>
> On 1 Jul 2008, at 10:52, Igal Koshevoy wrote:
> 
> > Marc Heiler wrote:
> > 
> > > Is there any way in ruby to create dynamic variables?
> > > 
> > > counter = 52  
> > > box#{counter} = "cat and dogs"
> > > 
> > > There would be then a new variable  
> > > box52
> > > 
> > > Note that this is not a question whether someone should do it or not -  
> > > this is solely whether it is doable or not. Until today I thought it is  
> > > somehow possible with eval but I failed, so I assume it is not possible.
> > 
> > irb(main):010:0\> counter = 52  
> > =\> 52  
> > irb(main):011:0\> eval "box#{counter} = 'cat and dogs'"  
> > =\> "cat and dogs"  
> > irb(main):012:0\> box52  
> > =\> "cat and dogs"

---

<div class="post-metadata">

### Author: ![stephen\_O\_D](https://avatars.discourse-cdn.com/v4/letter/s/51bf81/32.png) [@stephen\_O\_D](https://rubytalk.org/u/stephen_O_D)
#### Post date: [1 July 2008 15:37 UTC](https://rubytalk.org/t/dynamic-variables/47446/8 "2008-07-01T15:37:18Z")

</div>

Here here - I remember reading that article way back - the basic point  
of it is that if you want to create a variable on the fly, it probably  
means you should be using a Hash.

> **···**
>
> On Jul 1, 1:50 pm, Gregory Seidman \<gsslist+r...@anthropohedron.net\> wrote:
> 
> > On Tue, Jul 01, 2008 at 06:45:48PM +0900, Marc Heiler wrote:  
> > \> Is there any way in ruby to create dynamic variables?
> > 
> > \> counter = 52  
> > \> box#{counter} = "cat and dogs"
> > 
> > \> There would be then a new variable  
> > \> box52
> > 
> > \> Note that this is not a question whether someone should do it or not -  
> > \> this is solely whether it is doable or not. Until today I thought it is  
> > \> somehow possible with eval but I failed, so I assume it is not possible.
> > 
> > I'm going to give you exactly what you didn't ask for: why this is a bad  
> > idea. This is a discussion about Perl rather than Ruby, but it remains  
> > relevant:[Why it's stupid to `use a variable as a variable name'](http://perl.plover.com/varvarname.html)
> > 
> > See the subsequent parts of the series for further discussion.
> > 
> > --Greg

---

<div class="post-metadata">

### Author: ![He\_Ze\_Peng](https://avatars.discourse-cdn.com/v4/letter/h/8797f3/32.png) [@He\_Ze\_Peng](https://rubytalk.org/u/He_Ze_Peng)
#### Post date: [2 July 2008 00:24 UTC](https://rubytalk.org/t/dynamic-variables/47446/9 "2008-07-02T00:24:12Z")

</div>

Hello,  
&nbsp;&nbsp;&nbsp;&nbsp;How to get the IP address of client in ruby?  
thanks

---

<div class="post-metadata">

### Author: ![Igal\_Koshevoy](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@Igal\_Koshevoy](https://rubytalk.org/u/Igal_Koshevoy)
#### Post date: [1 July 2008 12:00 UTC](https://rubytalk.org/t/dynamic-variables/47446/10 "2008-07-01T12:00:00Z")

</div>

Frederick Cheung wrote:

> > irb(main):010:0\> counter = 52  
> > =\> 52  
> > irb(main):011:0\> eval "box#{counter} = 'cat and dogs'"  
> > =\> "cat and dogs"  
> > irb(main):012:0\> box52  
> > =\> "cat and dogs"
> 
> Although that doesn't work outside of irb. (although you can change the value of an existing local variable like that)  
> See also [http://groups.google.com/group/comp.lang.ruby/browse\_thread/thread/a954f8aaf698a0b9/e1c761b71b63b82e?#e1c761b71b63b82e](http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/a954f8aaf698a0b9/e1c761b71b63b82e?#e1c761b71b63b82e)

Thanks for catching the mistake and providing the link.

So there really is no way to get the "box52" variable directly? It's only available within the context of an eval?

When I run the code below directly (not from IRB), the interpreter is clearly seeing the "box52" local variable and keeping its state around, but won't let me access it without wrapping an eval around it, which seems wrong:

counter = 52  
p local\_variables # =\> ["counter"]  
eval "box#{counter} = 'cat and dogs'"  
p local\_variables # =\> ["counter", "box52"]  
p eval("box52") # =\> "cat and dogs"  
p box52 # =\> undefined local variable or method `box52' for main:Object (NameError)

I say "seems wrong" because I'm used to the following behavior:

# Python  
counter = 52  
eval(compile('box%s = "cat and dogs"' % counter, '\<string\>', 'exec'))  
print box52 # =\> "cat and dogs"

# Perl  
$counter = 52;  
eval("\$box$counter = 'cat and dogs'");  
print $box52, "\n"; # =\> "cat and dogs"

-igal

> **···**
>
> > On 1 Jul 2008, at 10:52, Igal Koshevoy wrote:

---

<div class="post-metadata">

### Author: ![Charles\_Oliver\_Nutte](https://avatars.discourse-cdn.com/v4/letter/c/71e660/32.png) [@Charles\_Oliver\_Nutte](https://rubytalk.org/u/Charles_Oliver_Nutte)
#### Post date: [1 July 2008 16:20 UTC](https://rubytalk.org/t/dynamic-variables/47446/11 "2008-07-01T16:20:13Z")

</div>

Igal Koshevoy wrote:

> # Python  
> counter = 52  
> eval(compile('box%s = "cat and dogs"' % counter, '\<string\>', 'exec'))  
> print box52 # =\> "cat and dogs"
> 
> # Perl  
> $counter = 52;  
> eval("\$box$counter = 'cat and dogs'");  
> print $box52, "\n"; # =\> "cat and dogs"

In python, local variables are not (necessarily) determined at parse/compile time. They're slots in a local scope that can grow later on.

In Ruby, this behavior only exists for eval scopes. Ruby 1.8 shares a single eval scope under any given normal scope across all evals in that normal scope. Ruby 1.9 instantiates a new eval scope for each eval.

I don't know what Perl does.

- Charlie

---

<div class="post-metadata">

### Author: ![Igal\_Koshevoy](https://avatars.discourse-cdn.com/v4/letter/i/8edcca/32.png) [@Igal\_Koshevoy](https://rubytalk.org/u/Igal_Koshevoy)
#### Post date: [1 July 2008 16:48 UTC](https://rubytalk.org/t/dynamic-variables/47446/12 "2008-07-01T16:48:16Z")

</div>

Charles Oliver Nutter wrote:

> Igal Koshevoy wrote:
> 
> > # Python  
> > counter = 52  
> > eval(compile('box%s = "cat and dogs"' % counter, '\<string\>', 'exec'))  
> > print box52 # =\> "cat and dogs"
> > 
> > # Perl  
> > $counter = 52;  
> > eval("\$box$counter = 'cat and dogs'");  
> > print $box52, "\n"; # =\> "cat and dogs"
> 
> In python, local variables are not (necessarily) determined at parse/compile time. They're slots in a local scope that can grow later on.
> 
> In Ruby, this behavior only exists for eval scopes. Ruby 1.8 shares a single eval scope under any given normal scope across all evals in that normal scope. Ruby 1.9 instantiates a new eval scope for each eval.
> 
> I don't know what Perl does.

Charles, thanks for the clarification about the scoping behaviors.

I suppose if I really want to pretend like I was dynamically injecting a local variable into a local scope, and a class/instance variable didn't weren't desirable, then I could resort to:

def set(name, value)  
&nbsp;&nbsp;self.class.send(:attr\_accessor, name)  
&nbsp;&nbsp;self.send("#{name}=", value)  
end

counter = 52  
set "box#{counter}", "cat and dogs"  
p box52 # =\> "cat and dogs"

-igal

---

<div class="post-metadata">

### Author: ![Charles\_Oliver\_Nutte](https://avatars.discourse-cdn.com/v4/letter/c/71e660/32.png) [@Charles\_Oliver\_Nutte](https://rubytalk.org/u/Charles_Oliver_Nutte)
#### Post date: [1 July 2008 19:57 UTC](https://rubytalk.org/t/dynamic-variables/47446/13 "2008-07-01T19:57:36Z")

</div>

Igal Koshevoy wrote:

> I suppose if I really want to pretend like I was dynamically injecting a local variable into a local scope, and a class/instance variable didn't weren't desirable, then I could resort to:
> 
> def set(name, value)  
> self.class.send(:attr\_accessor, name)  
> self.send("#{name}=", value)  
> end
> 
> counter = 52  
> set "box#{counter}", "cat and dogs"  
> p box52 # =\> "cat and dogs"

Yup, that would work except that for an attr\_accessor on self you need to qualify it with self.box52...so it wouldn't be quite seamless.

- Charlie
