# Module Eval Syntax

**URL:** <https://www.ruby-forum.com/t/module-eval-syntax/53155>\
**Category:** Ruby\
**Created:** [January 26, 2006, 9:17pm UTC](https://www.ruby-forum.com/t/module-eval-syntax/53155 "2006-01-26T21:17:01Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![John\_WSLong](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@John\_WSLong](https://www.ruby-forum.com/u/John_WSLong)\
**Post date:** [January 26, 2006, 9:17pm UTC](https://www.ruby-forum.com/t/module-eval-syntax/53155/1 "2006-01-26T21:17:01Z")

</div>

> > class MyModule; end  
> > =\> nil
> 
> > MyModule.class\_variables  
> > =\> []
> 
> > MyModule.module\_eval do  
> > ?\> @@test = true
> 
> > end  
> > =\> true
> 
> > @@test  
> > =\> true
> 
> > MyModule.module\_eval “@@weird = true”  
> > =\> true
> 
> > @@weird  
> > NameError: uninitialized class variable @@weird in Object  
> > from (irb):8
> 
> > MyModule.class\_variables  
> > =\> ["@@weird", “@@test”]
> 
> > Object.class\_variables  
> > =\> ["@@test"]

What in the world is going on here? Why does the block syntax eval  
differently than the string syntax? And why does @@test get defined on  
both MyModule and Object?

---

<div class="post-metadata">

**Author:** ![John\_WSLong](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/34f0e0/32.png) [@John\_WSLong](https://www.ruby-forum.com/u/John_WSLong)\
**Post date:** [January 26, 2006, 10:53pm UTC](https://www.ruby-forum.com/t/module-eval-syntax/53155/2 "2006-01-26T22:53:51Z")

</div>

This isn’t a direct answer to John’s question, but more an expansion of  
it that came up while I was playing with the original and my theory on  
what’s going on. Considering this IRB:

```
module MyModule; end
# => nil

MyModule.module_eval do
  @@mod_eval_var = "mev"
end
# => "mev"

MyModule.instance_eval do
  @@inst_eval_var = "iev"
end
# => "iev"

def MyModule.mkcv
  @@sing_meth_var = "smv"
end
# => nil

MyModule.mkcv
# => "smv"

module MyModule
  def self.mkcv2
    @@cls_sing_meth_var = "csmv"
  end
end
# => nil

MyModule.mkcv2
# => "csmv"

Object.class_variables
# => ["@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]
Class.class_variables
# => ["@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]
Module.class_variables
# => ["@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]
MyModule.class_variables
# => ["@@cls_sing_meth_var"]

```

Let me explain what I think I’m seeing here, and see if anyone can steer  
me right or expand on this behaviour. As far as I can tell, it seems  
that any time you make a @@class\_var outside of an actual class / module  
definition, you have to be extremely careful that you’re actually  
defining where you think you are. I would guess that any time Ruby sees  
an @@ variable, it immediately goes to the enclosing class and defines  
the variable there. Maybe that explains the block behaviour, because  
although the blocks are evaluated in the module they somehow retain  
their original enclosing object’s class - the top-level object in this  
case, of class Object.

The singleton method definition (def MyModule.mkcv) is actually creating  
a method on MyModule’s singleton class, which is just an instance of  
Class. The new method becomes an ‘instance method’ of that singleton  
class, so that @@sing\_meth\_var = “smv” results in Class (the #class of  
the singleton Class instance) getting another class variable. This is  
demonstrated by:

```
sc = module MyModule
  class << self; self; end
end
# => #<Class:MyModule>
sc.class
# => Class
sc.class_variables
# => ["@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]

```

If this is true, then it explains why the class variables are present  
across Object, Class and Module’s class variables - since all are  
instances of Class (and #class\_variables shows inherited vars). Since  
MyModule (an instance of class Module, a superclass of Class) doesn’t  
see these variables, I have to assume they do end up defined on Class.  
More generally, once a class variable is defined on either Class or  
Object (each being the class of the other) it is to all intents and  
purposes defined everywhere, given the class\_variables behaviour I  
mentioned above.

The final mkcv2 definition, by virtue of being inside a reopened module  
definition, _is_ defined as a a singleton method on MyModule, but either  
doesn’t go to the singleton class (instead being actually redefined on  
the Module instance), or else is treated specially (which I somehow  
doubt but is possible). In any event, this ends up being defined where  
we’d expect it.

To further check out the line between a class and it’s singleton class,  
I did a further experiment:

```
class SomeClazz
  @@icv = "icv"
end
# => "icv"

SomeClazz.class_variables
# => ["@@icv", "@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]

Class.class_variables
# => ["@@mod_eval_var", "@@inst_eval_var", "@@sing_meth_var"]

def SomeClazz.cval
  @@icv
end
# => nil

SomeClazz.cval
NameError: uninitialized class variable @@icv in Object
        from (irb):90:in `cval'
        from (irb):92
        from :0

class SomeClazz
  def self.mcval
    @@icv
  end
end
# => nil

SomeClazz.mcval
# => "icv"

```

This seems to confirm what I said above, and also (to me) is another  
great reason to stay away from class variables, especially when you’re  
talking about class variables on Class or Module instances.

Anyway, this is just theory of course, and especially with the block  
stuff  
it seems pretty mysterious - maybe even “surprising” - but it would seem  
to fit I think - A string eval obviously doesn’t close over it’s scope  
so  
wouldn’t be affected by it I guess. I hope someone can shed some more  
more light on this because it’s going to bug me now 😉
