# Singleton classes and Namespce

**URL:** <https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739>\
**Category:** Ruby\
**Created:** [June 6, 2010, 9:42pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739 "2010-06-06T21:42:29Z")\
**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:** [June 6, 2010, 9:42pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/1 "2010-06-06T21:42:29Z")

</div>

Do singleton classes not get the same namespace treatment as normal  
classes?

module M  
class X; end  
end

o = Object.new  
=\> #Object:0x7fc61f1a1e58

(class \<\< o; self; end).class\_eval{ include M }  
=\> #Object:0x7fc61f1a1e58

def o.x; X; end

o.x  
=\> NameError: uninitialized constant X  
from (irb):6:in `x’  
from (irb):7

The “(class \<\< o; self; end).class\_eval{ include M }” is effectively  
the same as “o.extend M” but I want to emphasize the use of #include.

It of course works fine if I use an explicit class.

class O  
include M  
def x; X; end  
end

O.new.x  
=\> M::X

---

<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:** [June 7, 2010, 11:35am UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/2 "2010-06-07T11:35:23Z")

</div>

2010/6/6 Intransition [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> Do singleton classes not get the same namespace treatment as normal  
> classes?

I think so.

> def o.x; X; end  
> This cannot work since X is not statically in scope.

> class O  
> include M  
> def x; X; end  
> end
> 
> O.new.x  
> =\> M::X

Yes, but you also changed something else: you defined the method  
inside the class body. So you did not only switch from class to  
singleton class but you also changed the lookup. It works if you  
define the method in the class body in the same way as you did for  
class O:

irb(main):001:0\> module M  
irb(main):002:1\> class X; end  
irb(main):003:1\> end  
=\> nil  
irb(main):004:0\> o = Object.new  
=\> #Object:0x1016f240  
irb(main):005:0\> (class \<\< o; self; end).class\_eval do  
irb(main):006:1\* include M  
irb(main):007:1\> def x; X; end  
irb(main):008:1\> end  
=\> nil  
irb(main):009:0\> o.x  
=\> M::X  
irb(main):010:0\> (class \<\< o; self; end).class\_eval do  
irb(main):011:1\* def y; X; end  
irb(main):012:1\> end  
=\> nil  
irb(main):013:0\> o.y  
=\> M::X  
irb(main):014:0\>

Kind regards

robert

---

<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:** [June 7, 2010, 3:52pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/3 "2010-06-07T15:52:58Z")

</div>

On 6/7/10, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > o = Object.new  
> > =\> #Object:0x7fc61f1a1e58
> > 
> > (class \<\< o; self; end).class\_eval{ include M }  
> > =\> #Object:0x7fc61f1a1e58
> > 
> > def o.x; X; end
> 
> This cannot work since X is not statically in scope.

Ah, but constant lookup is supposed to check the ancestors if the  
constant is not found in the scope. M should be among the ancestors of  
o’s singleton class, shouldn’t it? I would have expected this to work.  
OTOH, constant lookup is confusing.

This way works:

module M  
class X; end  
end

o = Object.new # =\> #Object:0x7fc61f1a1e58

(class \<\< o; self; end).class\_eval{ include M } # =\>  
#Object:0x7fc61f1a1e58  
#or o.extend M as well, presumably

class\<\<o  
def x; X end  
end

o.x #=\>M::X

See [http://ruby.runpaint.org/variables#constants](http://ruby.runpaint.org/variables#constants) in which the lookup  
rules are summarized as:  
(Module.nesting + container.ancestors + Object.ancestors).uniq  
#slightly paraphrased

I guess the key point to understand is that for singleton methods,  
container is the (static) module of class enclosing the singleton  
method, NOT the singleton class that they affect.

---

<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:** [June 7, 2010, 5:43pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/4 "2010-06-07T17:43:02Z")

</div>

On 6/7/10, Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 2010/6/7 Caleb C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > Ah, but constant lookup is supposed to check the ancestors if the  
> > constant is not found in the scope. M should be among the ancestors of  
> > o’s singleton class, shouldn’t it?
> 
> It does but you are not in the scope of the singleton class. Rather  
> you are in the toplevel (or any other) scope when you do “def o.x; X;  
> end”.

> > I guess the key point to understand is that for singleton methods,  
> > container is the (static) module of class enclosing the singleton  
> > method, NOT the singleton class that they affect.
> 
> Not sure I can follow you here. IMHO the key point is to understand  
> that it is a difference whether you open a scope (class, module) or  
> access the scope from the outside:

Sorry, I meant ‘module or class’, not ‘module of class’. Basically,  
I’m agreeing with what you said just above. It just took me a little  
longer to get to the same point of understanding about constant lookup  
that you were at. (Like I said: constant lookup is confusing.)

---

<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:** [June 7, 2010, 4:19pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/5 "2010-06-07T16:19:18Z")

</div>

2010/6/7 Caleb C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> > >
> 
> Ah, but constant lookup is supposed to check the ancestors if the  
> constant is not found in the scope. M should be among the ancestors of  
> o’s singleton class, shouldn’t it?

It does but you are not in the scope of the singleton class. Rather  
you are in the toplevel (or any other) scope when you do “def o.x; X;  
end”.

> (class \<\< o; self; end).class\_eval{ include M } # =\> #Object:0x7fc61f1a1e58  
> #or o.extend M as well, presumably
> 
> class\<\<o  
> def x; X end  
> end
> 
> o.x #=\>M::X

That’s basically the same what I did: you create the method in the  
singleton class’s scope.

> See [http://ruby.runpaint.org/variables#constants](http://ruby.runpaint.org/variables#constants) in which the lookup  
> rules are summarized as:  
> (Module.nesting + container.ancestors + Object.ancestors).uniq  
> #slightly paraphrased
> 
> I guess the key point to understand is that for singleton methods,  
> container is the (static) module of class enclosing the singleton  
> method, NOT the singleton class that they affect.

Not sure I can follow you here. IMHO the key point is to understand  
that it is a difference whether you open a scope (class, module) or  
access the scope from the outside:

irb(main):001:0\> module M  
irb(main):002:1\> class X; end  
irb(main):003:1\> O = Object.new  
irb(main):004:1\> end  
=\> #Object:0x101792b4  
irb(main):005:0\> def (M::O).x; X; end  
=\> nil  
irb(main):006:0\> M::O.x  
NameError: uninitialized constant X  
from (irb):5:in `x' from (irb):6 from /opt/bin/irb19:12:in `’  
irb(main):007:0\> module M  
irb(main):008:1\> def O.y; X; end  
irb(main):009:1\> end  
=\> nil  
irb(main):010:0\> M::O.y  
=\> M::X  
irb(main):011:0\> def (M::O).x; M::X; end  
=\> nil  
irb(main):012:0\> M::O.x  
=\> M::X

Kind regards

robert

---

<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:** [June 7, 2010, 6:22pm UTC](https://www.ruby-forum.com/t/singleton-classes-and-namespce/189739/6 "2010-06-07T18:22:16Z")

</div>

Thanks Robert and Caleb. At least it makes sense --even if it doesn’t  
make sense 😉

> Seehttp://ruby.runpaint.org/variables#constantsin which the lookup  
> rules are summarized as:  
> (Module.nesting + container.ancestors + Object.ancestors).uniq  
> #slightly paraphrased
> 
> I guess the key point to understand is that for singleton methods,  
> container is the (static) module of class enclosing the singleton  
> method, NOT the singleton class that they affect.

I supposed, but that doesn’t seem quite right, as the document pointed  
out that “self.ancestors” should be looked up. Shouldn’t that catch  
the singleton class too?

Honestly. Something is not right if these are not the same:

class \<\< o  
def x; X end  
end

def o.x; X; end

~trans
