# Mixing Constants into objects

**URL:** <https://rubytalk.org/t/mixing-constants-into-objects/20147>\
**Category:** ruby-talk\
**Created:** [14 August 2005 11:51 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147 "2005-08-14T11:51:12Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![gabriele\_renzi5](https://avatars.discourse-cdn.com/v4/letter/g/e79b87/32.png) [@gabriele\_renzi5](https://rubytalk.org/u/gabriele_renzi5)\
**Post date:** [14 August 2005 11:51 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/1 "2005-08-14T11:51:12Z")

</div>

Hi gurus and nubys,

is there a way to add a constant into an object which is not a module/class?

Basically what I'd like is some kind of append\_features/include that works on non-module objects.  
Is my only chance to mess up with the singleton class by myself, or there is some existing method for this?

Thanks in advance

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [14 August 2005 12:14 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/2 "2005-08-14T12:14:38Z")

</div>

Hi --

> Hi gurus and nubys,
> 
> is there a way to add a constant into an object which is not a module/class?
> 
> Basically what I'd like is some kind of append\_features/include that works on non-module objects.
> 
> Is my only chance to mess up with the singleton class by myself, or there is some existing method for this?

If I understand you correctly, I think Kernel#extend is what you need:

&nbsp;&nbsp;&nbsp;irb(main):001:0\> s = ""  
&nbsp;&nbsp;&nbsp;=\> ""  
&nbsp;&nbsp;&nbsp;irb(main):002:0\> module M; X=1; end  
&nbsp;&nbsp;&nbsp;=\> 1  
&nbsp;&nbsp;&nbsp;irb(main):003:0\> s.extend(M)  
&nbsp;&nbsp;&nbsp;=\> ""  
&nbsp;&nbsp;&nbsp;irb(main):004:0\> (class \<\< s; self; end)::X  
&nbsp;&nbsp;&nbsp;=\> 1

I think that's the closest thing corresponding to "adding a constant"  
to an arbitrary object (adding it to the object's singleton class).

David

> **···**
>
> On Sun, 14 Aug 2005, gabriele renzi wrote:
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![gabriele\_renzi5](https://avatars.discourse-cdn.com/v4/letter/g/e79b87/32.png) [@gabriele\_renzi5](https://rubytalk.org/u/gabriele_renzi5)\
**Post date:** [14 August 2005 12:51 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/3 "2005-08-14T12:51:12Z")

</div>

David A. Black ha scritto:

> Hi --
> 
> > Hi gurus and nubys,
> > 
> > is there a way to add a constant into an object which is not a module/class?
> > 
> > Basically what I'd like is some kind of append\_features/include that works on non-module objects.
> > 
> > Is my only chance to mess up with the singleton class by myself, or there is some existing method for this?
> 
> If I understand you correctly, I think Kernel#extend is what you need:
> 
> &nbsp;&nbsp;irb(main):001:0\> s = ""  
> &nbsp;&nbsp;=\> ""  
> &nbsp;&nbsp;irb(main):002:0\> module M; X=1; end  
> &nbsp;&nbsp;=\> 1  
> &nbsp;&nbsp;irb(main):003:0\> s.extend(M)  
> &nbsp;&nbsp;=\> ""  
> &nbsp;&nbsp;irb(main):004:0\> (class \<\< s; self; end)::X  
> &nbsp;&nbsp;=\> 1
> 
> I think that's the closest thing corresponding to "adding a constant"  
> to an arbitrary object (adding it to the object's singleton class).

well, ri explicitly says for #extend:  
" Adds to \_obj\_ the instance methods from each module given as a  
&nbsp;&nbsp;parameter"  
and this is omitting Constants, which are available when something is #include'd  
See example:

I won't be able to access singleton class constants from the singleton instance, it seems:

\>\> class Foo  
\>\> def barer  
\>\> Bar.new  
\>\> end  
\>\> end  
=\> nil  
\>\> module M  
\>\> class Bar  
\>\> end  
\>\> end  
=\> nil  
\>\> foo=Foo.new  
=\> #\<Foo:0x2d01428\>  
\>\> foo.extend M  
=\> #\<Foo:0x2d01428\>  
\>\> foo.barer # I'd like to get a Bar instance here  
NameError: uninitialized constant Foo2::Bar  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):12:in `barer'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):21

I don't understand why, actually.

> **···**
>
> > On Sun, 14 Aug 2005, gabriele renzi wrote:

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [14 August 2005 14:24 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/4 "2005-08-14T14:24:07Z")

</div>

Hi --

> David A. Black ha scritto:
> 
> > Hi --
> > 
> > > Hi gurus and nubys,
> > > 
> > > is there a way to add a constant into an object which is not a module/class?
> > > 
> > > Basically what I'd like is some kind of append\_features/include that works on non-module objects.
> > > 
> > > Is my only chance to mess up with the singleton class by myself, or there is some existing method for this?
> > 
> > If I understand you correctly, I think Kernel#extend is what you need:
> > 
> > &nbsp;&nbsp;irb(main):001:0\> s = ""  
> > &nbsp;&nbsp;=\> ""  
> > &nbsp;&nbsp;irb(main):002:0\> module M; X=1; end  
> > &nbsp;&nbsp;=\> 1  
> > &nbsp;&nbsp;irb(main):003:0\> s.extend(M)  
> > &nbsp;&nbsp;=\> ""  
> > &nbsp;&nbsp;irb(main):004:0\> (class \<\< s; self; end)::X  
> > &nbsp;&nbsp;=\> 1
> > 
> > I think that's the closest thing corresponding to "adding a constant"  
> > to an arbitrary object (adding it to the object's singleton class).
> 
> well, ri explicitly says for #extend:  
> " Adds to \_obj\_ the instance methods from each module given as a  
> parameter"  
> and this is omitting Constants, which are available when something is #include'd

I'm not sure what you mean by "adding a constant to an object" if the  
object isn't a Class or Module. For example:

&nbsp;&nbsp;&nbsp;obj = Object.new  
&nbsp;&nbsp;&nbsp;obj.constants =\> no such method

All constants live in a class/module namespace. That's what I mean  
when I say the closest you can get is adding it to an object's  
singleton class.

> See example:
> 
> I won't be able to access singleton class constants from the singleton instance, it seems:
> 
> > > class Foo  
> > > def barer  
> > > &nbsp;&nbsp;Bar.new  
> > > end  
> > > end
> 
> =\> nil
> 
> > > module M  
> > > class Bar  
> > > end  
> > > end
> 
> =\> nil
> 
> > > foo=Foo.new
> 
> =\> #\<Foo:0x2d01428\>
> 
> > > foo.extend M
> 
> =\> #\<Foo:0x2d01428\>
> 
> > > foo.barer # I'd like to get a Bar instance here
> 
> NameError: uninitialized constant Foo2::Bar

Where did "Foo2" come from? I get Foo::Bar 🙂

> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):12:in `barer'  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):21
> 
> I don't understand why, actually.

I think it's this: when an instance method refers to a constant, that  
constant is looked up in the class where the method is defined.  
Therefore, in your example, Foo#barer looks for Foo::Bar.

So it's not the same as a method call, where it would be looked up in  
the object's singleton class. I guess that's because constants really  
belong to classes, not to objects generally. So when you ask for a  
constant, the class you're in doesn't branch off and look in other  
classes.

This may have to do with the way constant references are parsed, which  
is kind of quasi-static.

Anyway, here's an illustration.

class Foo  
&nbsp;&nbsp;def x  
&nbsp;&nbsp;&nbsp;&nbsp;p X  
&nbsp;&nbsp;end  
end

foo = Foo.new

class \<\< foo  
&nbsp;&nbsp;&nbsp;X = 1  
&nbsp;&nbsp;&nbsp;Y = 1  
&nbsp;&nbsp;&nbsp;def y  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p Y  
&nbsp;&nbsp;&nbsp;end  
end

foo.y =\> 1 (that's \<foo's singleton class\>::Y)  
foo.x =\> uninitialized constant Foo::X  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(foo's singleton class isn't involved)

David

> **···**
>
> On Sun, 14 Aug 2005, gabriele renzi wrote:
> 
> > > On Sun, 14 Aug 2005, gabriele renzi wrote:
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![Dave\_Burt1](https://avatars.discourse-cdn.com/v4/letter/d/ebca7d/32.png) [@Dave\_Burt1](https://rubytalk.org/u/Dave_Burt1)\
**Post date:** [14 August 2005 23:21 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/5 "2005-08-14T23:21:12Z")

</div>

class Foo  
&nbsp;&nbsp;def barer  
&nbsp;&nbsp;&nbsp;bar.new  
&nbsp;&nbsp;end  
end  
module M  
&nbsp;&nbsp;class Bar  
&nbsp;&nbsp;end  
&nbsp;&nbsp;def bar() Bar end  
end  
foo=Foo.new  
foo.extend M  
foo.barer #=\> #\<Foo::Bar:0x2940eb8\>

---

<div class="post-metadata">

**Author:** ![Devin\_Mullins](https://avatars.discourse-cdn.com/v4/letter/d/958977/32.png) [@Devin\_Mullins](https://rubytalk.org/u/Devin_Mullins)\
**Post date:** [14 August 2005 14:37 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/6 "2005-08-14T14:37:44Z")

</div>

As David said, the constant accessed in whatever class is specified by the class...end block you're currently in. Example:

class Moo; MOO = 'hi' end  
class Foo; MOO = 'burp' end  
class Foo  
def Moo.greet; p MOO end  
end  
class Moo  
def Moo.bark; p MOO end  
end

irb(main):009:0\> Moo.bark  
"hi"  
irb(main):010:0\> Moo.greet  
"burp"

Constants share this property with class variables.

So, if you want to inject a factory into your class, you're going to have to use a different method, or play around with const\_set.

Devin

---

<div class="post-metadata">

**Author:** ![gabriele\_renzi5](https://avatars.discourse-cdn.com/v4/letter/g/e79b87/32.png) [@gabriele\_renzi5](https://rubytalk.org/u/gabriele_renzi5)\
**Post date:** [14 August 2005 15:01 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/7 "2005-08-14T15:01:15Z")

</div>

David A. Black ha scritto:

> > well, ri explicitly says for #extend:  
> > " Adds to \_obj\_ the instance methods from each module given as a  
> > parameter"  
> > and this is omitting Constants, which are available when something is #include'd
> 
> I'm not sure what you mean by "adding a constant to an object" if the  
> object isn't a Class or Module. For example:
> 
> &nbsp;&nbsp;obj = Object.new  
> &nbsp;&nbsp;obj.constants =\> no such method
> 
> All constants live in a class/module namespace. That's what I mean  
> when I say the closest you can get is adding it to an object's  
> singleton class.

you're right as usual 🙂  
what I meant is adding them \*somewhere\* so that they're available to the object. Basically I wondered if ruby had something able to do the singleton class hackery withouth me noticing it, like extend does for instance methods (but after reading the rest now I understand why this can't work)

> > NameError: uninitialized constant Foo2::Bar
> 
> Where did "Foo2" come from? I get Foo::Bar 🙂

emh.. evil little creatures acting on my desktop, I'd say..

> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):12:in `barer'  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):21
> > 
> > I don't understand why, actually.
> 
> I think it's this: when an instance method refers to a constant, that  
> constant is looked up in the class where the method is defined.  
> Therefore, in your example, Foo#barer looks for Foo::Bar.
> 
> So it's not the same as a method call, where it would be looked up in  
> the object's singleton class. I guess that's because constants really  
> belong to classes, not to objects generally. So when you ask for a  
> constant, the class you're in doesn't branch off and look in other  
> classes.

ah, this makes a lot of sense, thanks

> This may have to do with the way constant references are parsed, which  
> is kind of quasi-static.

mh.. maybe "lexical" is the better word ?

> Anyway, here's an illustration.
> 
> class Foo  
> def x  
> &nbsp;&nbsp;&nbsp;p X  
> end  
> end
> 
> foo = Foo.new
> 
> class \<\< foo  
> &nbsp;&nbsp;X = 1  
> &nbsp;&nbsp;Y = 1  
> &nbsp;&nbsp;def y  
> &nbsp;&nbsp;&nbsp;&nbsp;p Y  
> &nbsp;&nbsp;end  
> end
> 
> foo.y =\> 1 (that's \<foo's singleton class\>::Y)  
> foo.x =\> uninitialized constant Foo::X  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(foo's singleton class isn't involved)

thanks for the explanation, this makes sense now.

---

<div class="post-metadata">

**Author:** ![David\_A\_Black3](https://avatars.discourse-cdn.com/v4/letter/d/6a8cbe/32.png) [@David\_A\_Black3](https://rubytalk.org/u/David_A_Black3)\
**Post date:** [14 August 2005 16:00 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/8 "2005-08-14T16:00:54Z")

</div>

Hi --

> **···**
>
> On Mon, 15 Aug 2005, gabriele renzi wrote:
> 
> > I wrote:
> > 
> > > This may have to do with the way constant references are parsed, which  
> > > is kind of quasi-static.
> > 
> > mh.. maybe "lexical" is the better word ?
> 
> I think it's more than that. What I should have said was: constant  
> references are resolved at parse-time, rather than run-time. At least  
> I think that's the case.
> 
> David
> 
> --  
> David A. Black  
> dblack@wobblini.net

---

<div class="post-metadata">

**Author:** ![Caleb\_Clausen1](https://avatars.discourse-cdn.com/v4/letter/c/8dc957/32.png) [@Caleb\_Clausen1](https://rubytalk.org/u/Caleb_Clausen1)\
**Post date:** [15 August 2005 20:21 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/9 "2005-08-15T20:21:59Z")

</div>

Just how constant lookups work is something of a mystery to me in some  
cases... it's clearly less dynamic than method lookup, but it is  
run-time lookup, not compile time:

irb(main):001:0\> class K  
irb(main):002:1\> Foo=1  
irb(main):003:1\> end  
=\> 1  
irb(main):004:0\> def fk; K::Foo end  
=\> nil  
irb(main):005:0\> fk  
=\> 1  
irb(main):006:0\> class K  
irb(main):007:1\> Foo=2  
irb(main):008:1\> end  
(irb):7: warning: already initialized constant Foo  
=\> 2  
irb(main):009:0\> fk  
=\> 2

> **···**
>
> On 8/14/05, David A. Black \<dblack@wobblini.net\> wrote:
> 
> > On Mon, 15 Aug 2005, gabriele renzi wrote:  
> > \> mh.. maybe "lexical" is the better word ?
> > 
> > I think it's more than that. What I should have said was: constant  
> > references are resolved at parse-time, rather than run-time. At least  
> > I think that's the case.

---

<div class="post-metadata">

**Author:** ![Wilson\_Bilkovich](https://yyz1.discourse-cdn.com/flex029/user_avatar/rubytalk.org/wilson_bilkovich/32/8247_2.png) [@Wilson\_Bilkovich](https://rubytalk.org/u/Wilson_Bilkovich)\
**Post date:** [15 August 2005 20:51 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/10 "2005-08-15T20:51:09Z")

</div>

My (possibly totally off-base) understanding is that, as there is no  
'compile' step in Ruby, the constants get 'burned' into the AST, as do  
things like regular expression literals, between forward-slashes.  
That would explain why they "look" like runtime evaluations, but they  
aren't the same kind of citizen as variables.

> **···**
>
> On 8/15/05, Caleb Clausen \<vikkous@gmail.com\> wrote:
> 
> > On 8/14/05, David A. Black \<dblack@wobblini.net\> wrote:  
> > \> On Mon, 15 Aug 2005, gabriele renzi wrote:  
> > \> \> mh.. maybe "lexical" is the better word ?  
> > \>  
> > \> I think it's more than that. What I should have said was: constant  
> > \> references are resolved at parse-time, rather than run-time. At least  
> > \> I think that's the case.
> > 
> > Just how constant lookups work is something of a mystery to me in some  
> > cases... it's clearly less dynamic than method lookup, but it is  
> > run-time lookup, not compile time:
> > 
> > irb(main):001:0\> class K  
> > irb(main):002:1\> Foo=1  
> > irb(main):003:1\> end  
> > =\> 1  
> > irb(main):004:0\> def fk; K::Foo end  
> > =\> nil  
> > irb(main):005:0\> fk  
> > =\> 1  
> > irb(main):006:0\> class K  
> > irb(main):007:1\> Foo=2  
> > irb(main):008:1\> end  
> > (irb):7: warning: already initialized constant Foo  
> > =\> 2  
> > irb(main):009:0\> fk  
> > =\> 2

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [15 August 2005 21:31 UTC](https://rubytalk.org/t/mixing-constants-into-objects/20147/11 "2005-08-15T21:31:34Z")

</div>

Caleb Clausen wrote:

> > > mh.. maybe "lexical" is the better word ?
> > 
> > I think it's more than that. What I should have said was: constant  
> > references are resolved at parse-time, rather than run-time. At least  
> > I think that's the case.
> 
> Just how constant lookups work is something of a mystery to me in some  
> cases... it's clearly less dynamic than method lookup, but it is  
> run-time lookup, not compile time:
> 
> irb(main):001:0\> class K  
> irb(main):002:1\> Foo=1  
> irb(main):003:1\> end  
> =\> 1  
> irb(main):004:0\> def fk; K::Foo end  
> =\> nil  
> irb(main):005:0\> fk  
> =\> 1  
> irb(main):006:0\> class K  
> irb(main):007:1\> Foo=2  
> irb(main):008:1\> end  
> (irb):7: warning: already initialized constant Foo  
> =\> 2  
> irb(main):009:0\> fk  
> =\> 2

Constant binding is normally static:

class K  
Foo=1  
end

def fk; K::Foo end

fk

class K  
Foo=2  
end

p fk # ==\> 2

module M  
&nbsp;&nbsp;class K  
&nbsp;&nbsp;&nbsp;&nbsp;Foo=3  
&nbsp;&nbsp;end  
&nbsp;&nbsp;p fk # ==\> 2  
&nbsp;&nbsp;p K::Foo # ==\> 3  
end

# However, you can force dynamic constant binding:

def sfk; self::K::Foo; end

module M  
&nbsp;&nbsp;p sfk # ==\> 3  
end

> **···**
>
> > On 8/14/05, David A. Black \<dblack@wobblini.net\> wrote:
> > 
> > > On Mon, 15 Aug 2005, gabriele renzi wrote:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
