Scope of constants in instance_eval

so If I do<br>

class MyObj < Module<br>
   CONST = 'xxx'<br>

   def initalialize(&block)<br>
      super(&block)<br>
   end<br>
end<br>
<br>
MyObj.new do<br>
    puts("CONST = #{CONST}")<br>
end<br>
<br>
<br>
# this will print<br>
unitialized constant CONST<br>
<br>
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 :slight_smile:

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"

···

--
Posted via http://www.ruby-forum.com/.

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:

so If I do<br>

class MyObj < Module<br>
  CONST = 'xxx'<br>

  def initalialize(&block)<br>
     super(&block)<br>
  end<br>
end<br>
<br>
MyObj.new do<br>
   puts("CONST = #{CONST}")<br>
end<br>
<br>
# this will print<br>
unitialized constant CONST<br>
<br>
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 :slight_smile:

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"
--
Posted via http://www.ruby-forum.com/\.

--
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

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 :slight_smile:

Florian Gilcher 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:

<br>
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/\.

--
Florian Gilcher

smtp: flo@andersground.net
jabber: Skade@jabber.ccc.de
gpg: 533148E2

--
Posted via http://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.

···

On Oct 10, 8:48 am, Peter Pk <pet...@livingwork.com> wrote:

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 :slight_smile:

Florian Gilcher 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:

>> <br>
>> 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 viahttp://www.ruby-forum.com/.

> --
> Florian Gilcher

> smtp: f...@andersground.net
> jabber: Sk...@jabber.ccc.de
> gpg: 533148E2

--
Posted viahttp://www.ruby-forum.com/.

I got 1.9 and am now running it :slight_smile:
thanks!

pharrington wrote:

···

On Oct 10, 8:48�am, Peter Pk <pet...@livingwork.com> wrote:

> change
>> <br>
> smtp: � f...@andersground.net
> jabber: Sk...@jabber.ccc.de
> 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.

--
Posted via http://www.ruby-forum.com/\.

pharrington 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 :slight_smile: 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 :slight_smile:

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

···

On Oct 10, 8:48�am, Peter Pk <pet...@livingwork.com> wrote:

> change
>> <br>
> smtp: � f...@andersground.net
> jabber: Sk...@jabber.ccc.de
> 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")}" }

--
Posted via http://www.ruby-forum.com/\.

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

···

--
Posted via http://www.ruby-forum.com/\.