# The subtleties of const\_missing

**URL:** <https://rubytalk.org/t/the-subtleties-of-const-missing/22513>\
**Category:** ruby-talk\
**Created:** [16 November 2005 04:36 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513 "2005-11-16T04:36:46Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nicholas\_Seckar](https://avatars.discourse-cdn.com/v4/letter/n/b77776/32.png) [@Nicholas\_Seckar](https://rubytalk.org/u/Nicholas_Seckar)\
**Post date:** [16 November 2005 04:36 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/1 "2005-11-16T04:36:46Z")

</div>

Hello all,

I've run into an issue regarding the use of const\_missing. This issue revolves around the fact that these two cases are supposed to behave differently from each other:

irb(main):001:0\> B = 10  
irb(main):002:0\> module A; B; end  
=\> 10  
irb(main):003:0\> A::B  
NameError: uninitialized constant A::B  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3

However it seems impossible to detect which case we are in within the const\_missing method. A more detailed explanation follows:

Suppose we are lazy and avoid typing "require 'my\_module.rb'" by defining a const\_missing that performs that require when MyModule is first referenced. Now, suppose we are writing my\_class, and wish to include MyModule. So, we put this code in my\_class.rb:

class MyClass  
&nbsp;&nbsp;&nbsp;include MyModule  
&nbsp;&nbsp;&nbsp;...  
end

Our const\_missing handler is called, and it loads 'my\_module.rb', finds the now present MyModule constant, and returns it. Everything is good.

However, let's say we're slightly misguided and do MyClass::MyModule. Since this is not defined, our const\_missing handler is once again called. 'my\_module.rb' is thus loaded again, (usually to no effect,) and MyModule returned.

This is a pretty clear violation of the semantics of ::. Indeed, Ruby will produce a warning regarding our misbehaved const\_missing. That said, there does not seem to be a way to behave correctly; from inside the const\_missing handler there is no way to tell which case the constant is missing in.

One way to 'fix' this is to have our const\_missing look in it's parent modules for the missing constant. If we find it there, we know this is a case of A::B. However this only works if the missing constant has been defined in one of the parents. Thus, we can still load ::B using A::B, but afterwards A::B will fail.

So, sorry for rambling on. The real question is: Can const\_missing detect if we are in a "A::B" case rather than "module A; B; end" ?

Thanks for your time and any replies,  
Regards,  
Nicholas Seckar

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [16 November 2005 04:57 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/2 "2005-11-16T04:57:12Z")

</div>

but why do you need to distinguish?

&nbsp;&nbsp;&nbsp;harp:~ \> cat a.rb  
&nbsp;&nbsp;&nbsp;class Module  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def const\_missing c  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "const\_missing..."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const\_set c, 42  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;module A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p B  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p A::B

&nbsp;&nbsp;&nbsp;harp:~ \> ruby a.rb  
&nbsp;&nbsp;&nbsp;const\_missing...  
&nbsp;&nbsp;&nbsp;42

the 'const\_missing' hook will continue to get call only so long as it remain  
undefined - if your handler merely loads a file but does not actually define  
any const then of course it will continue to fire. what, exactly, does your  
handler do?

kind regards.

-a

> **···**
>
> On Wed, 16 Nov 2005, Nicholas Seckar wrote:
> 
> > Hello all,
> > 
> > I've run into an issue regarding the use of const\_missing. This issue revolves around the fact that these two cases are supposed to behave differently from each other:
> > 
> > irb(main):001:0\> B = 10  
> > irb(main):002:0\> module A; B; end  
> > =\> 10  
> > irb(main):003:0\> A::B  
> > NameError: uninitialized constant A::B  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3
> > 
> > However it seems impossible to detect which case we are in within the  
> > const\_missing method. A more detailed explanation follows:
> > 
> > Suppose we are lazy and avoid typing "require 'my\_module.rb'" by defining a  
> > const\_missing that performs that require when MyModule is first referenced.  
> > Now, suppose we are writing my\_class, and wish to include MyModule. So, we  
> > put this code in my\_class.rb:
> > 
> > class MyClass  
> > include MyModule  
> > ...  
> > end
> > 
> > Our const\_missing handler is called, and it loads 'my\_module.rb', finds the  
> > now present MyModule constant, and returns it. Everything is good.
> > 
> > However, let's say we're slightly misguided and do MyClass::MyModule. Since  
> > this is not defined, our const\_missing handler is once again called.  
> > 'my\_module.rb' is thus loaded again, (usually to no effect,) and MyModule  
> > returned.
> > 
> > This is a pretty clear violation of the semantics of ::. Indeed, Ruby will  
> > produce a warning regarding our misbehaved const\_missing. That said, there  
> > does not seem to be a way to behave correctly; from inside the const\_missing  
> > handler there is no way to tell which case the constant is missing in.
> > 
> > One way to 'fix' this is to have our const\_missing look in it's parent  
> > modules for the missing constant. If we find it there, we know this is a  
> > case of A::B. However this only works if the missing constant has been  
> > defined in one of the parents. Thus, we can still load ::B using A::B, but  
> > afterwards A::B will fail.
> > 
> > So, sorry for rambling on. The real question is: Can const\_missing detect if  
> > we are in a "A::B" case rather than "module A; B; end" ?
> 
> # --
> 
> > ara [dot] t [dot] howard [at] gmail [dot] com  
> > all happiness comes from the desire for others to be happy. all misery  
> > comes from the desire for oneself to be happy.  
> > -- bodhicaryavatara
> 
> ===============================================================================

---

<div class="post-metadata">

**Author:** ![Eric\_Hodel1](https://avatars.discourse-cdn.com/v4/letter/e/a9adbd/32.png) [@Eric\_Hodel1](https://rubytalk.org/u/Eric_Hodel1)\
**Post date:** [16 November 2005 05:27 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/3 "2005-11-16T05:27:45Z")

</div>

I have found this type of laziness often leads to errors that are difficult to discover because somewhere else a MyModule was defined leaving the file I really want to use unrequired.

require 'my\_module' is really not that hard to type.

> **···**
>
> On Nov 15, 2005, at 8:36 PM, Nicholas Seckar wrote:
> 
> > Hello all,
> > 
> > I've run into an issue regarding the use of const\_missing. This issue revolves around the fact that these two cases are supposed to behave differently from each other:
> > 
> > irb(main):001:0\> B = 10  
> > irb(main):002:0\> module A; B; end  
> > =\> 10  
> > irb(main):003:0\> A::B  
> > NameError: uninitialized constant A::B  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3
> > 
> > However it seems impossible to detect which case we are in within the const\_missing method. A more detailed explanation follows:
> > 
> > Suppose we are lazy and avoid typing "require 'my\_module.rb'" by defining a const\_missing that performs that require when MyModule is first referenced. Now, suppose we are writing my\_class, and wish to include MyModule. So, we put this code in my\_class.rb:
> 
> --  
> Eric Hodel - drbrain@segment7.net - [http://segment7.net](http://segment7.net)  
> FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

---

<div class="post-metadata">

**Author:** ![Nakada\_Nobuyoshi](https://avatars.discourse-cdn.com/v4/letter/n/848f3c/32.png) [@Nakada\_Nobuyoshi](https://rubytalk.org/u/Nakada_Nobuyoshi)\
**Post date:** [16 November 2005 05:34 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/4 "2005-11-16T05:34:15Z")

</div>

Hi,

At Wed, 16 Nov 2005 13:36:46 +0900,  
Nicholas Seckar wrote in [ruby-talk:165996]:

> I've run into an issue regarding the use of const\_missing. This issue  
> revolves around the fact that these two cases are supposed to behave  
> differently from each other:
> 
> irb(main):001:0\> B = 10  
> irb(main):002:0\> module A; B; end  
> =\> 10  
> irb(main):003:0\> A::B  
> NameError: uninitialized constant A::B  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3
> 
> However it seems impossible to detect which case we are in within the  
> const\_missing method. A more detailed explanation follows:

What about autoload?

&nbsp;&nbsp;$ echo 'B = 10' \> b.rb

&nbsp;&nbsp;$ irb  
&nbsp;&nbsp;irb(main):001:0\> autoload :B, "b"  
&nbsp;&nbsp;=\> nil  
&nbsp;&nbsp;irb(main):002:0\> module A;end  
&nbsp;&nbsp;=\> nil  
&nbsp;&nbsp;irb(main):003:0\> A::B  
&nbsp;&nbsp;NameError: uninitialized constant A::B  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3  
&nbsp;&nbsp;irb(main):004:0\> module A;B;end  
&nbsp;&nbsp;=\> 10  
&nbsp;&nbsp;irb(main):005:0\> A::B  
&nbsp;&nbsp;NameError: uninitialized constant A::B  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):5  
&nbsp;&nbsp;irb(main):006:0\>

> **···**
>
> from :0  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from :0
> 
> --  
> Nobu Nakada

---

<div class="post-metadata">

**Author:** ![Robert](https://avatars.discourse-cdn.com/v4/letter/r/e95f7d/32.png) [@Robert](https://rubytalk.org/u/Robert)\
**Post date:** [16 November 2005 10:37 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/5 "2005-11-16T10:37:18Z")

</div>

Nicholas Seckar wrote:

> Hello all,
> 
> I've run into an issue regarding the use of const\_missing. This issue  
> revolves around the fact that these two cases are supposed to behave  
> differently from each other:
> 
> irb(main):001:0\> B = 10  
> irb(main):002:0\> module A; B; end  
> =\> 10  
> irb(main):003:0\> A::B  
> NameError: uninitialized constant A::B  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3
> 
> However it seems impossible to detect which case we are in within the  
> const\_missing method. A more detailed explanation follows:

I'm not sure what you're up to. You define B in a completely different  
scope than you use for lookup. Maybe you can give a more real life  
example of what you are actually trying to do.

Kind regards

&nbsp;&nbsp;&nbsp;&nbsp;robert

---

<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:** [16 November 2005 14:42 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/6 "2005-11-16T14:42:03Z")

</div>

Hi,

Rails does this very thing. You should check out their const\_missing and see if it suffers from the self-same problem.

Devin

Nicholas Seckar wrote:

> **···**
>
> > Hello all,
> > 
> > I've run into an issue regarding the use of const\_missing. This issue revolves around the fact that these two cases are supposed to behave differently from each other:
> > 
> > irb(main):001:0\> B = 10  
> > irb(main):002:0\> module A; B; end  
> > =\> 10  
> > irb(main):003:0\> A::B  
> > NameError: uninitialized constant A::B  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from (irb):3
> > 
> > However it seems impossible to detect which case we are in within the const\_missing method. A more detailed explanation follows:
> > 
> > Suppose we are lazy and avoid typing "require 'my\_module.rb'" by defining a const\_missing that performs that require when MyModule is first referenced. Now, suppose we are writing my\_class, and wish to include MyModule. So, we put this code in my\_class.rb:
> > 
> > class MyClass  
> > &nbsp;&nbsp;include MyModule  
> > &nbsp;&nbsp;...  
> > end
> > 
> > Our const\_missing handler is called, and it loads 'my\_module.rb', finds the now present MyModule constant, and returns it. Everything is good.
> > 
> > However, let's say we're slightly misguided and do MyClass::MyModule. Since this is not defined, our const\_missing handler is once again called. 'my\_module.rb' is thus loaded again, (usually to no effect,) and MyModule returned.
> > 
> > This is a pretty clear violation of the semantics of ::. Indeed, Ruby will produce a warning regarding our misbehaved const\_missing. That said, there does not seem to be a way to behave correctly; from inside the const\_missing handler there is no way to tell which case the constant is missing in.
> > 
> > One way to 'fix' this is to have our const\_missing look in it's parent modules for the missing constant. If we find it there, we know this is a case of A::B. However this only works if the missing constant has been defined in one of the parents. Thus, we can still load ::B using A::B, but afterwards A::B will fail.
> > 
> > So, sorry for rambling on. The real question is: Can const\_missing detect if we are in a "A::B" case rather than "module A; B; end" ?
> > 
> > Thanks for your time and any replies,  
> > Regards,  
> > Nicholas Seckar

---

<div class="post-metadata">

**Author:** ![Nicholas\_Seckar](https://avatars.discourse-cdn.com/v4/letter/n/b77776/32.png) [@Nicholas\_Seckar](https://rubytalk.org/u/Nicholas_Seckar)\
**Post date:** [16 November 2005 05:02 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/7 "2005-11-16T05:02:49Z")

</div>

The loaded file is expected to define the constant; We assume b.rb contains class or module B (or defines it in any other way). If the constant isn't defined by the loaded file then a NameError is raised as if normal.

> **···**
>
> On 15-Nov-05, at 11:57 PM, Ara.T.Howard wrote:
> 
> > but why do you need to distinguish?
> > 
> > [snip]
> > 
> > the 'const\_missing' hook will continue to get call only so long as it remain  
> > undefined - if your handler merely loads a file but does not actually define  
> > any const then of course it will continue to fire. what, exactly, does your  
> > handler do?

---

<div class="post-metadata">

**Author:** ![Ara.T.Howard6](https://avatars.discourse-cdn.com/v4/letter/a/958977/32.png) [@Ara.T.Howard6](https://rubytalk.org/u/Ara.T.Howard6)\
**Post date:** [16 November 2005 13:47 UTC](https://rubytalk.org/t/the-subtleties-of-const-missing/22513/8 "2005-11-16T13:47:06Z")

</div>

> The loaded file is expected to define the constant; We assume b.rb contains  
> class or module B (or defines it in any other way). If the constant isn't  
> defined by the loaded file then a NameError is raised as if normal.

i understand that. but in your original message you said

> However, let's say we're slightly misguided and do MyClass::MyModule. Since  
> this is not defined, our const\_missing handler is once again called.  
> 'my\_module.rb' is thus loaded again, (usually to no effect,) and MyModule  
> returned.
> 
> This is a pretty clear violation of the semantics of ::. Indeed, Ruby will  
> produce a warning regarding our misbehaved const\_missing. That said, there  
> does not seem to be a way to behave correctly; from inside the const\_missing  
> handler there is no way to tell which case the constant is missing in.

here you will see that wether we reference B from inside M, or as M::B the  
handler is called exactly once.

&nbsp;&nbsp;&nbsp;harp:~ \> cat a.rb  
&nbsp;&nbsp;&nbsp;class Module  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def const\_missing c  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "const\_missing called once..."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const\_set c, 42  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;module A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p B  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;p A::B

&nbsp;&nbsp;&nbsp;harp:~ \> ruby a.rb  
&nbsp;&nbsp;&nbsp;const\_missing called once...  
&nbsp;&nbsp;&nbsp;42

here is another example which loads a file

&nbsp;&nbsp;&nbsp;harp:~ \> cat a.rb  
&nbsp;&nbsp;&nbsp;class Module  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def const\_missing c  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;puts "const\_missing called once..."  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;autoload = {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;:B =\> 'b.rb'  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;autoload[c] ? require(autoload[c]) : super  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const\_set(c, const\_get(c))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;module A  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;B  
&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;module A; p B; end  
&nbsp;&nbsp;&nbsp;p A::B

&nbsp;&nbsp;&nbsp;harp:~ \> ruby a.rb  
&nbsp;&nbsp;&nbsp;const\_missing called once...  
&nbsp;&nbsp;&nbsp;42

so what \_\_exactly\_\_ are you trying to do in your handler that does not work? i  
understand you problem but, as the second example shows, it can easily be  
solved without distinguishing the two syntax cases because, afaikt, ruby  
handles them precisely the same.

hth.

-a

> **···**
>
> # On Wed, 16 Nov 2005, Nicholas Seckar wrote: &nbsp;&nbsp;&nbsp;A::B --
> 
> > ara [dot] t [dot] howard [at] gmail [dot] com  
> > all happiness comes from the desire for others to be happy. all misery  
> > comes from the desire for oneself to be happy.  
> > -- bodhicaryavatara
> 
> ===============================================================================
