# Scope of constants in instance\_eval

**URL:** <https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034>\
**Category:** Ruby\
**Created:** [October 10, 2009, 4:44am UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034 "2009-10-10T04:44:53Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 10, 2009, 4:44am UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/1 "2009-10-10T04:44:53Z")

</div>

so If I do

class MyObj \< Module  
  
CONST = ‘xxx’

def initalialize(&block)  
  
super(&block)  
  
end  
  
end  
  
  
  
MyObj.new do  
  
puts(“CONST = #{CONST}”)  
  
end

# this will print

unitialized constant CONST  
  
  
  
So how do I create a “constant” ie: attribute with leading upper case  
char that is resolvable within “instance\_eval()” for a particular  
instance of a class that defines the constant or subclass of it or class  
that includes a module that defines the constant?

I tried overriding “const\_missing” but as a static method on class  
Object I see no way to determine the “self” that was active when the  
constant was not resolved, If so I could then make it happen, by  
examinig the “self” for it’s class etc and look for the constants in  
them 🙂

Kind of like i’d like to be able to get caller[0].binding.self inside  
“const\_missing”

This so it can be like Java to get “this.CONST”

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 10, 2009, 5:52am UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/2 "2009-10-10T05:52:07Z")

</div>

This is a bit of a strange problem. Ruby 1.8 resolves constants  
lexically.

So you are actually referring to ::CONST there.

In Ruby 1.9, this is different. In Ruby 1.9, Constants are resolved by  
´self´.  
So, in short:

class A  
module B  
end  
end

A.new.instance\_eval do  
B  
end

crashes in 1.8, but resolves B as A::B in 1.9. Some people hate that  
change  
in behaviour, I like it.

It doesn’t directly answer your question, but I hope it gives you  
enough insight to find a way to do what you want.

Regards,  
Florian

On Oct 10, 2009, at 12:14 AM, Peter Pk wrote:

> instance of a class that defines the constant or subclass of it or "const\_missing"
> ## This so it can be like Java to get “this.CONST”
> 
> Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).

–  
Florian G.

smtp: removed\_email\_address@domain.invalid  
jabber: removed\_email\_address@domain.invalid  
gpg: 533148E2

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 10, 2009, 2:48pm UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/3 "2009-10-10T14:48:37Z")

</div>

Thanks - actually it does answer the question, but it also answers that  
I have to wait until Ruby 1.9 for the “fix”

that is unless there is a workaround way (until 1.9) to

doInConstanScopeOf [Module] do

# so instead of ‘Module::CONST’ one can do ‘CONST’

end

so one could do

def doIt(&block)  
doInConstanScopeOf AModule &block  
end

and explicitly define the constant scope to be the scope of “self.class”

so when will the fabled 1.9 be available 🙂

Florian G. wrote:

> This is a bit of a strange problem. Ruby 1.8 resolves constants  
> lexically.
> 
> So you are actually referring to ::CONST there.
> 
> In Ruby 1.9, this is different. In Ruby 1.9, Constants are resolved by  
> ï¿½selfï¿½.  
> So, in short:
> 
> class A  
> module B  
> end  
> end
> 
> A.new.instance\_eval do  
> B  
> end
> 
> crashes in 1.8, but resolves B as A::B in 1.9. Some people hate that  
> change  
> in behaviour, I like it.
> 
> It doesn’t directly answer your question, but I hope it gives you  
> enough insight to find a way to do what you want.
> 
> Regards,  
> Florian
> 
> On Oct 10, 2009, at 12:14 AM, Peter Pk wrote:
> 
> > instance of a class that defines the constant or subclass of it or "const\_missing"
> > ## This so it can be like Java to get “this.CONST”
> > 
> > Posted via [http://www.ruby-forum.com/](http://www.ruby-forum.com/).
> 
> –  
> Florian G.
> 
> smtp: removed\_email\_address@domain.invalid  
> jabber: removed\_email\_address@domain.invalid  
> gpg: 533148E2

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 10, 2009, 4:00pm UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/4 "2009-10-10T16:00:45Z")

</div>

On Oct 10, 8:48 am, Peter Pk [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > change
> > 
> > > 
> > 
> > smtp: removed\_email\_address@domain.invalid  
> > jabber: removed\_email\_address@domain.invalid  
> > gpg: 533148E2
> 
> –  
> Posted viahttp://www.ruby-forum.com/.

well in Ruby 1.8 something like this works (obviously not it all  
cases, but you get the gist and can fix it as needed):

Obj.new { puts “CONST = #{self.class.const\_get(“CONST”)}” }

And what do you mean by “waiting” until Ruby 1.9? 1.9.1’s been  
released and stable for the better part of this year now.

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 10, 2009, 9:03pm UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/5 "2009-10-10T21:03:16Z")

</div>

I got 1.9 and am now running it 🙂  
thanks!

pharrington wrote:

> On Oct 10, 8:48ï¿½am, Peter Pk [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > > change
> > > 
> > > > 
> > > 
> > > smtp: ï¿½ removed\_email\_address@domain.invalid  
> > > jabber: removed\_email\_address@domain.invalid  
> > > gpg: ï¿½ ï¿½533148E2
> > 
> > –  
> > Posted viahttp://www.ruby-forum.com/.
> 
> well in Ruby 1.8 something like this works (obviously not it all  
> cases, but you get the gist and can fix it as needed):
> 
> Obj.new { puts “CONST = #{self.class.const\_get(“CONST”)}” }
> 
> And what do you mean by “waiting” until Ruby 1.9? 1.9.1’s been  
> released and stable for the better part of this year now.

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 11, 2009, 3:38pm UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/6 "2009-10-11T15:38:09Z")

</div>

pharrington wrote:

> On Oct 10, 8:48ï¿½am, Peter Pk [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> And what do you mean by “waiting” until Ruby 1.9? 1.9.1’s been  
> released and stable for the better part of this year now.

That there are convenient installers/packages/etc available and  
documented for the OS’ and distros that our admin sets up our  
development machines for 🙂 It looks like one still has to compile from  
source in many cases (such as Fedora). Windows was easy as someone made  
an NSIS installer 🙂

BTW 1.9 does exactly what I want and that is to overide const\_missing on  
a specific class. The old behavior also still works if not overidden  
(as the static method on Object, but the “self” will be the self of the  
object that was missing the constant. IMHO way better behavior to allow  
object oriented overides.

One can also on a specific class do:

alias :const\_missing : **send**

which will (efficiently) if a const is missing direct it to an attribute  
of the same name so you don’t have to do thing = XXX() and can access it  
by thing = XXX

> > > change
> > > 
> > > > 
> > > 
> > > smtp: ï¿½ removed\_email\_address@domain.invalid  
> > > jabber: removed\_email\_address@domain.invalid  
> > > gpg: ï¿½ ï¿½533148E2
> > 
> > –  
> > Posted viahttp://www.ruby-forum.com/.
> 
> well in Ruby 1.8 something like this works (obviously not it all  
> cases, but you get the gist and can fix it as needed):
> 
> Obj.new { puts “CONST = #{self.class.const\_get(“CONST”)}” }

---

<div class="post-metadata">

**Author:** ![peterk](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/p/7993a0/32.png) [@peterk](https://www.ruby-forum.com/u/peterk)\
**Post date:** [October 13, 2009, 10:52am UTC](https://www.ruby-forum.com/t/scope-of-constants-in-instance-eval/177034/7 "2009-10-13T10:52:54Z")

</div>

pharrington wrote:

> well in Ruby 1.8 something like this works (obviously not it all  
> cases, but you get the gist and can fix it as needed):
> 
> Obj.new { puts “CONST = #{self.class.const\_get(“CONST”)}” }

Or more simply, self.class::CONST

I find this particularly useful when I wish to override a constant in a  
subclass, e.g.

class Foo  
TIMEOUT = 10  
def run  
puts “Timeout is #{self.class::TIMEOUT}”  
end  
end

class Bar \< Foo  
TIMEOUT = 20  
end

Bar.new.run

Note that you need this trick even in ruby 1.9.2. Without it, the  
constant is still resolved statically, depending on in which class the  
method was defined:

$ irb19 --simple-prompt

> > RUBY\_VERSION  
> > =\> “1.9.2”
> 
> > RUBY\_DESCRIPTION  
> > =\> “ruby 1.9.2dev (2009-07-18 trunk 24186) [i686-linux]”
> 
> > class Foo  
> > TIMEOUT = 10  
> > def run  
> > puts “Timeout is #{TIMEOUT}”  
> > end  
> > end  
> > =\> nil
> 
> > class Bar \< Foo  
> > TIMEOUT = 20  
> > end  
> > =\> 20
> 
> > Bar.new.run  
> > Timeout is 10  
> > =\> nil
> 
> > class Bar  
> > def run2  
> > puts “Timeout is #{TIMEOUT}”  
> > end  
> > end  
> > =\> nil
> 
> > Bar.new.run2  
> > Timeout is 20 ## ruby1.8 shows 10 here  
> > =\> nil
