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
>        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" ?

but why do you need to distinguish?

   harp:~ > cat a.rb
   class Module
     def const_missing c
       puts "const_missing..."
       const_set c, 42
     end
   end

   module A
     p B
   end

   p A::B

   harp:~ > ruby a.rb
   const_missing...
   42
   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
-- 
===============================================================================
| 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
===============================================================================