# Programmatically creating a local variable using a symol

**URL:** <https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164>\
**Category:** Ruby\
**Created:** [January 6, 2008, 2:50pm UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164 "2008-01-06T14:50:48Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 6, 2008, 2:50pm UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/1 "2008-01-06T14:50:48Z")

</div>

Hi,

Where are variables actually stored? Or rather: how do I create a new  
variable without using eval?

I’d like to write something like this.

```
bind :a, 1
p a
=> 1

```

How could I accompish this? How could a definition of “bind” look  
like?

Local variables are registered in Binding and local\_variables, but  
how  
do I get them there? = is no method, but it’s no keyword either?

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 6, 2008, 3:52pm UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/2 "2008-01-06T15:52:30Z")

</div>

On Jan 6, 2008 8:49 AM, tho\_mica\_l [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Where are variables actually stored? Or rather: how do I create a new  
> variable without using eval?

Why do you want to do this with a local variable?

Consider using a hash and make your own “binding” table for the  
purposes of which you’re speaking.

-austin

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 6, 2008, 5:35pm UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/3 "2008-01-06T17:35:53Z")

</div>

> Why do you want to do this with a local variable?

First, I’d like to know a little bit more about ruby. And I would  
have  
found such a thing useful once or twice in the past.

Secondly (the background for my question), I’d like to implement some  
ocaml’ish match command (for the moment, as some kind of exercise  
only).  
I’m not sure yet how this could best be done but I thought it would  
be  
nice if it could look somewhat like this:

```
val = Foo(1, 2)

case val
when Foo(:x, :y)
    a = x * y
when Bar(:x)
    a = x
end

```

But this form would require the variables to be set from Foo#=== which  
I  
don’t think is possible anyway.

What I managed to do is this:

```
class Matchtype
  class << self
      def match(other, &block)
          if other.class == self
              block.call(*other.value)
              true
          else
              false
          end
      end
  end

  attr_reader :value

  def initialize(*value)
      @value = value
  end

end

```

Sample use:

```
class Foo < Matchtype
end

class Bar < Matchtype
end

x = Foo.new(1, 2)
y = Bar.new(1)

if Foo.match(x) {|a, b| p "Foo", a + b}
elsif Bar.match(x) {|a| p "Bar", a}
end

if Foo.match(y) {|a, b| p "Foo", a + b}
elsif Bar.match(y) {|a| p "Bar", a}
end

```

But this is quite useless the way it is because the value of the  
block  
cannot be used and because it’s ugly and …

One could of course do it this way which would come close:

```
class Boo < Array
end

class Baa < Array
end

z = Boo[1, 2]
case z
when Baa
    p "Nope"
when Boo
    a, b = z
    p "Boo", a + b
end

```

It would be nice being able to eliminate the “a, b = z” line though.

Ideally, one would also be able to do something like this:

```
z = Boo[1, :a]
case z
when Boo(0, '')
    p "Nope"
when Boo(1, :a)
    p "Boo", a
end

```

Any ideas are welcome.

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 6, 2008, 6:21pm UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/4 "2008-01-06T18:21:41Z")

</div>

On Jan 6, 2008, at 9:34 AM, tho\_mica\_l wrote:

> nice if it could look somewhat like this:
> 
> ```
> val = Foo(1, 2)
> 
> case val
> when Foo(:x, :y)
> a = x * y
> when Bar(:x)
> a = x
> end
> 
> ```

invert the var binding: make them instance variables and it falls out  
easily:

class Foo  
attr :x, :y  
def initialize x, y  
@x, @y = x, y  
end  
end  
def Foo(\*a, &b) Foo.new(\*a, &b) end

class Bar \< Foo; end  
def Bar(\*a, &b) Bar.new(\*a, &b) end

val = Foo 1, 2

a =  
case val  
when Foo  
val.x \* val.y  
when Bar  
val.x  
end

a @ [http://codeforpeople.com/](http://codeforpeople.com/)

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 7, 2008, 8:12am UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/5 "2008-01-07T08:12:59Z")

</div>

On Jan 7, 2008 12:45 AM, tho\_mica\_l [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> (I still would like to know if it’s possible to create a local  
> variable  
> though.)

You might have to use #instance\_eval.

irb\> a = “hello”  
=\> “hello”  
irb\> instance\_eval( “#{a} = 3” )  
=\> 3  
irb\> a  
=\> “hello”  
irb\> hello  
=\> 3

Not much help, but sort of answers the question.

Todd

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 7, 2008, 7:45am UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/6 "2008-01-07T07:45:31Z")

</div>

> invert the var binding: make them instance variables and it falls out  
> easily:

Okay, this idea with the variable binding is pointless in this  
context.  
(I still would like to know if it’s possible to create a local  
variable  
though.)

I now defined a subclass of Array with a more clever === method,  
which  
knows how to match wildcards. This version comes pretty close to what  
I  
intended.

```
class Foo < MatchStruct
    fields :a, :b, :c, :d, :e
end

class Bar < MatchStruct
    fields :a, :b
end

x = Foo[1, 2, 3, 4, 5]
a = MatchStruct(x) do
    match Foo[1, :_, 3, :_, 5] do
        ["Foo", *x]
    end
    match Bar[:_, "b"] do
        ["Bar", x.a + x.b]
    end
end
p a

```

Regards,  
Thomas.

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 7, 2008, 9:05am UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/7 "2008-01-07T09:05:35Z")

</div>

> You might have to use #instance\_eval.

This is about what I try to avoid. Some interpreters make variables  
available via some pseudomagic dictionary/hash. Based on ruby’s nature  
and my previous experiences I’d assumed ruby would provide such a  
solution too but couldn’t find it out myself.

---

<div class="post-metadata">

**Author:** ![tho\_mica\_l](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/e480ec/32.png) [@tho\_mica\_l](https://www.ruby-forum.com/u/tho_mica_l)\
**Post date:** [January 7, 2008, 9:17am UTC](https://www.ruby-forum.com/t/programmatically-creating-a-local-variable-using-a-symol/125164/8 "2008-01-07T09:17:54Z")

</div>

tho\_mica\_l wrote:

> > You might have to use #instance\_eval.
> 
> This is about what I try to avoid. Some interpreters make variables  
> available via some pseudomagic dictionary/hash. Based on ruby’s nature  
> and my previous experiences I’d assumed ruby would provide such a  
> solution too but couldn’t find it out myself.

There is no way in either Ruby 1.8 or Ruby 1.9. The names of variables  
and “variable calls” are determined at parse time, both for normal  
scopes and for eval. eval can add new variables, but only to the eval  
scope, and only in 1.8 (I believe 1.9 provides a separate eval scope for  
each eval).

Your only change of dynamically defining things that look like variables  
is the attr binding a few people have described.

- Charlie
