a little challenge - reproduce this error

I

Intransition

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 ;-)
 
S

Steve Klabnik

[Note: parts of this message were removed to make it a legal post.]

throw NameError.new("uninitialized constant X::Foo::X")
 
J

John Feminella

This is a pretty trivial error to generate. Just reference the
constant that doesn't exist:

$ irb
ruby-1.9.2-p180 :001 > module X; module Foo; end; end
=> nil
ruby-1.9.2-p180 :002 > X::Foo::X
NameError: uninitialized constant X::Foo::X

~ jf
 
I

Intransition

This is a pretty trivial error to generate. Just reference the
constant that doesn't exist:

$ irb
ruby-1.9.2-p180 :001 > module X; module Foo; end; end
=A0=3D> nil
ruby-1.9.2-p180 :002 > X::Foo::X
NameError: uninitialized constant X::Foo::X

Ah good point. I made an assumption. A qualifier then: X does exist.
How about this must be as top of your solution.

module X; end
 
C

Christopher Dicely

Ah good point. I made an assumption. A qualifier then: X does exist.
How about this must be as top of your solution.

=C2=A0 =C2=A0module X; end

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.
 
M

Michael Edgar

The easiest way to get the error you ask about is
module X; module Foo; end; end
X::Foo::X
=20
But I would guess that that probably isn't what you are looking for =
either.

It wouldn't be, because that's not an error: it ends up referencing the =
top-level X from inside Foo, giving this warning:

(irb):1407: warning: toplevel constant X referenced by X::Foo::X

Michael Edgar
(e-mail address removed)
http://carboni.ca/
 
I

Intransition

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 eithe=
r.

Yes, in the actual code X is being referenced from within Foo but is
not fully qualified.
 
I

Intransition

her.

It wouldn't be, because that's not an error: it ends up referencing the t=
op-level X from inside Foo, giving this warning:
(irb):1407: warning: toplevel constant X referenced by X::Foo::X

Interesting. What platform on you on?
 
I

Intransition

Interesting. What platform on you on?

s/on/are/

I've always been pretty bad with the typos, but I swear this week I've
gone into dyslexic overdrive. My apologies.
 
M

Michael Edgar

=20
=20

=20
Interesting. What platform on you on?
=20

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.

Michael Edgar
(e-mail address removed)
http://carboni.ca/
 
M

Michael Edgar

=20
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.
=20
In fact, I can't even produce that error in 1.9.2.
=20
It works the same both 1.8.7, 1.9.1, and 1.9.2 for me.
=20
--=20
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

... 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.

Sorry for the confusion/noise,

Michael Edgar
(e-mail address removed)
http://carboni.ca/
 
C

Christopher Dicely

It wouldn't be, because that's not an error: it ends up referencing the top-level X from inside Foo, giving this warning:

(irb):1407: warning: toplevel constant X referenced by X::Foo::X

Michael Edgar
(e-mail address removed)
http://carboni.ca/
 
C

Christopher Dicely

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.
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.
 
I

Intransition

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.

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.
 
J

John Feminella

I realize now maybe how I should have phrased this as a challenge
=C2=A0 =C2=A0module X
=C2=A0 =C2=A0 =C2=A0class Foo
=C2=A0 =C2=A0 =C2=A0 =C2=A0def call
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0X
=C2=A0 =C2=A0 =C2=A0 =C2=A0end
=C2=A0 =C2=A0 =C2=A0end
=C2=A0 =C2=A0end

Change one line of this code to cause this error:

=C2=A0uninitialized 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?
 
I

Intransition

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?

When #call is invoked, the error is raised. So yea, guess I should
have added:

X::Foo.new.call
 
J

Josh Cheek

[Note: parts of this message were removed to make it a legal post.]

When #call is invoked, the error is raised. So yea, guess I should
have added:

X::Foo.new.call
Well, I give up :)
 
I

Intransition

Well, I give up :)

I bet a few people have come across it without fully knowing what was
going on and just fixed their issue by adding `::` to the "X". That's
what I did a few times before I realized what the hell was going on.

The change needed to cause the error is this:

module X
class Foo < BasicObject
def call
X
end
end
end

Right off you can see this only effect Ruby 1.9+ (b/c 1.8 has no
BasicObject).

Next up... why it happens and how to fix.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,566
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top