# Ruby 1.9.2 Constant Lookup with BasicObject

**URL:** <https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125>\
**Category:** Ruby\
**Created:** [August 30, 2010, 6:48pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125 "2010-08-30T18:48:24Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 30, 2010, 6:48pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/1 "2010-08-30T18:48:24Z")

</div>

ruby-1.9.2-p0 \> module M  
ruby-1.9.2-p0 ?\> end  
=\> nil  
ruby-1.9.2-p0 \> class X \< BasicObject  
ruby-1.9.2-p0 ?\> include M  
ruby-1.9.2-p0 ?\> end  
NameError: uninitialized constant X::M  
from (irb):4:in `<class:X>' from (irb):3 from /home/trans/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in`’

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 31, 2010, 2:50pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/2 "2010-08-31T14:50:21Z")

</div>

module M is defined inside Object space.  
X is one level above it - it is inside BasicObject( where no Object  
space is visible)  
Inside X you try to include an object from other space (one level below)  
I think it will work if you include Object::M

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 31, 2010, 4:24pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/3 "2010-08-31T16:24:36Z")

</div>

On Aug 31, 8:50 am, Eugen C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > =\> nil  
> > ruby-1.9.2-p0\> class X\< BasicObject  
> > ruby-1.9.2-p0 ?\> include M  
> > ruby-1.9.2-p0 ?\> end  
> > NameError: uninitialized constant X::M  
> > from (irb):4:in `<class:X>' from (irb):3 from /home/trans/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’

I filed a bug report on Ruby’s issue tracker and matz brought up the  
same. Here’s my take:

I see the technical reason it occurs, but to accept that as proper  
behavior is going to hobble the usefulness of BasicObject.

First of all, it means one’s ability to open a class and modify it  
will be conditional. One will have to check if it is a BasicObject  
upfront. That’s easy to do if you’re working with one class you  
already know, but consider how it effects doing some meta-programming  
where code is injected into any arbitrary class.

Worst still is that it makes importing code into a namespace very  
fragile. Consider the simplistic example of having some code in a  
script to eval into a module.

module M  
eval(File.read(‘file.rb’))  
end

If file.rb contains:

class R  
end

class Q \< BasicObject  
def r; R.new; end  
end

Then it will break whether we use R or ::R.

I feel the underlying issue here goes back to some other issues we’ve  
discussed some years ago about the top-level. Routing the toplevel to  
Object is not as flexible or robust as having a toplevel be an  
independent self-extended module in which constant resolution would  
terminate.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 31, 2010, 4:30pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/4 "2010-08-31T16:30:28Z")

</div>

The rules of constant name resolution have changed with BasicObject.  
There was a step before that said that if nesting and ancestors didn’t  
find it, you checked Object.

I’d like to know the current complete algorithm, including const\_missing  
calls.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 31, 2010, 4:28pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/5 "2010-08-31T16:28:07Z")

</div>

Hi,

I understand your complain. But the solution should be concrete, and  
hopefully consistent with other parts of the language. I am not sure  
your “a toplevel being an independent self-extended module” proposal  
is the way to go (yet).

```
          matz.

```

In message “Re: Ruby 1.9.2 Constant Lookup with BasicObject”  
on Tue, 31 Aug 2010 23:23:53 +0900, Intransition  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:  
|  
|On Aug 31, 8:50 am, Eugen C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
|\> module M is defined inside Object space.  
|\> X is one level above it - it is inside BasicObject( where no Object  
|\> space is visible)  
|\> Inside X you try to include an object from other space (one level below)  
|\> I think it will work if you include Object::M  
|\>  
|\> On 08/30/2010 07:47 PM, Intransition wrote:  
|\>  
|\> \> ruby-1.9.2-p0\> module M  
|\> \> ruby-1.9.2-p0 ?\> end  
|\> \> =\> nil  
|\> \> ruby-1.9.2-p0\> class X\< BasicObject  
|\> \> ruby-1.9.2-p0 ?\> include M  
|\> \> ruby-1.9.2-p0 ?\> end  
|\> \> NameError: uninitialized constant X::M  
|\> \> from (irb):4:in `<class:X>' |> > from (irb):3 |> > from /home/trans/.rvm/rubies/ruby-1.9.2-p0/bin/irb:17:in `’  
|  
|I filed a bug report on Ruby’s issue tracker and matz brought up the  
|same. Here’s my take:  
|  
|I see the technical reason it occurs, but to accept that as proper  
|behavior is going to hobble the usefulness of BasicObject.  
|  
|First of all, it means one’s ability to open a class and modify it  
|will be conditional. One will have to check if it is a BasicObject  
|upfront. That’s easy to do if you’re working with one class you  
|already know, but consider how it effects doing some meta-programming  
|where code is injected into any arbitrary class.  
|  
|Worst still is that it makes importing code into a namespace very  
|fragile. Consider the simplistic example of having some code in a  
|script to eval into a module.  
|  
| module M  
| eval(File.read(‘file.rb’))  
| end  
|  
|If file.rb contains:  
|  
| class R  
| end  
|  
| class Q \< BasicObject  
| def r; R.new; end  
| end  
|  
|Then it will break whether we use R or ::R.  
|  
|I feel the underlying issue here goes back to some other issues we’ve  
|discussed some years ago about the top-level. Routing the toplevel to  
|Object is not as flexible or robust as having a toplevel be an  
|independent self-extended module in which constant resolution would  
|terminate.

---

<div class="post-metadata">

**Author:** ![tcsnide](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/eb8c5e/32.png) [@tcsnide](https://www.ruby-forum.com/u/tcsnide)\
**Post date:** [August 31, 2010, 7:30pm UTC](https://www.ruby-forum.com/t/ruby-1-9-2-constant-lookup-with-basicobject/194125/6 "2010-08-31T19:30:14Z")

</div>

After some trial and error it seems the algorithm is the same as in  
1.8 if we take into account that the special rule that checks Object  
as a last resort applies only to modules.
