Want to see a really amazing error I got this week? Okay... but to
make it more interesting I am going to the change some names to
protect the innocent, and offer up a little challenge: How can
reproduce it?
The error is this:
uninitialized constant X::Foo::X (NameError)
Did you catch that?
Think you can solve it?
I imagine your mind is getting a bit mushy about now
The top-level X (and the Foo underneath it) seems required to get the
error, so that doesn't make it harder. If you reference X::Foo::X
without X existing, you'll get
uninitialized constant Object::X (NameError)
If you reference X::Foo::X with just the part you have above, you'll
get uninitialized constant X::Foo (NameError)
The easiest way to get the error you ask about is
module X; module Foo; end; end
X::Foo::X
But I would guess that that probably isn't what you are looking for either.
···
On Wed, Jun 8, 2011 at 6:43 AM, Intransition <transfire@gmail.com> wrote:
On Jun 8, 9:20 am, John Feminella <jo...@bitsbuilder.com> wrote:
This is a pretty trivial error to generate. Just reference the
constant that doesn't exist:
The top-level X (and the Foo underneath it) seems required to get the
error, so that doesn't make it harder. If you reference X::Foo::X
without X existing, you'll get
uninitialized constant Object::X (NameError)
If you reference X::Foo::X with just the part you have above, you'll
get uninitialized constant X::Foo (NameError)
The easiest way to get the error you ask about is
module X; module Foo; end; end
X::Foo::X
Well, Balls. That in itself seems ridiculous, but you are right. I'm
not sure why it raises that though. Maybe the code is silly, but is it
really wrong? Try X::Foo.const_get(:X) and it works fine. Seems
inconsistent, doesn't it?
But I would guess that that probably isn't what you are looking for either.
Yes, in the actual code X is being referenced from within Foo but is
not fully qualified.
···
On Jun 8, 10:56 am, Christopher Dicely <cmdic...@gmail.com> wrote:
The top-level X (and the Foo underneath it) seems required to get the
error, so that doesn't make it harder. If you reference X::Foo::X
without X existing, you'll get
uninitialized constant Object::X (NameError)
If you reference X::Foo::X with just the part you have above, you'll
get uninitialized constant X::Foo (NameError)
The easiest way to get the error you ask about is
module X; module Foo; end; end
X::Foo::X
Well, Balls. That in itself seems ridiculous, but you are right. I'm
not sure why it raises that though. Maybe the code is silly, but is it
really wrong? Try X::Foo.const_get(:X) and it works fine. Seems
inconsistent, doesn't it?
Not really. I'd expect X::Foo::X to get the constant at that path
(which doesn't exist, hence the error), while X::Foo.const_get(:X) I'd
expect to resolve as if X was referenced within X::Foo, including
climbing up the chain, and to return the top-level X.
But I would guess that that probably isn't what you are looking for
either.
Yes, in the actual code X is being referenced from within Foo but is
not fully qualified.
I could swear that I have run into that error in some things in the
past (and resolved it by fully qualifying the affected references),
but now I can't figure out how to reproduce it.
···
On Wed, Jun 8, 2011 at 8:27 AM, Intransition <transfire@gmail.com> wrote:
On Jun 8, 10:56 am, Christopher Dicely <cmdic...@gmail.com> wrote:
That was on 1.9.2p188. Seems to be a change in 1.9 - I started checking against other RVM installs
after seeing your response that X::Foo::X gives an error. I could've sworn I understood the differences
in constant resolution between 1.9.2 and 1.8.7... back to the drawing board there, I guess.
In fact, I can't even produce that error in 1.9.2.
I realize now maybe how I should have phrased this as a challenge
module X
class Foo
def call
X
end
end
end
Change one line of this code to cause this error:
uninitialized constant X::Foo::X (NameError)
and without directly calling #raise.
Something like that anyway. Hindsight being 20/20 and all. Of course,
I made it a challenge simply b/c I thought it would be a bit more
interesting that way.
I let this sit for a bit longer then I'll give the lowdown and a
useful tip on how to deal with it when it arises.
···
On Jun 8, 8:39 pm, Christopher Dicely <cmdic...@gmail.com> wrote:
I could swear that I have run into that error in some things in the
past (and resolved it by fully qualifying the affected references),
but now I can't figure out how to reproduce it.
It works the same both 1.8.7, 1.9.1, and 1.9.2 for me.
···
On Thu, Jun 09, 2011 at 12:39:56AM +0900, Michael Edgar wrote:
That was on 1.9.2p188. Seems to be a change in 1.9 - I started checking
against other RVM installs after seeing your response that X::Foo::X
gives an error. I could've sworn I understood the differences in
constant resolution between 1.9.2 and 1.8.7... back to the drawing
board there, I guess.
In fact, I can't even produce that error in 1.9.2.
I realize now maybe how I should have phrased this as a challenge
module X
class Foo
def call
X
end
end
end
Change one line of this code to cause this error:
uninitialized constant X::Foo::X (NameError)
and without directly calling #raise.
Just to be clear, do you mean "without invoking #call" (as in, pasting
this into irb should raise the error), or is the intention that #call
will be invoked?
... and my contribution becomes meaningless. Ugh. I closed my irb session and re-opened
it, and now can't repro the top-level dereference. If I can, I'll post, but I'm guessing I should
have just used a fresh session instead one that appears to have been 1500 evaluations deep.
On Thu, Jun 09, 2011 at 12:39:56AM +0900, Michael Edgar wrote:
That was on 1.9.2p188. Seems to be a change in 1.9 - I started checking
against other RVM installs after seeing your response that X::Foo::X
gives an error. I could've sworn I understood the differences in
constant resolution between 1.9.2 and 1.8.7... back to the drawing
board there, I guess.
In fact, I can't even produce that error in 1.9.2.
It works the same both 1.8.7, 1.9.1, and 1.9.2 for me.
When #call is invoked, the error is raised. So yea, guess I should
have added:
X::Foo.new.call
···
On Jun 9, 1:22 pm, John Feminella <jo...@bitsbuilder.com> wrote:
> I realize now maybe how I should have phrased this as a challenge
> module X
> class Foo
> def call
> X
> end
> end
> end
> Change one line of this code to cause this error:
> uninitialized constant X::Foo::X (NameError)
> and without directly calling #raise.
Just to be clear, do you mean "without invoking #call" (as in, pasting
this into irb should raise the error), or is the intention that #call
will be invoked?