A little challenge - reproduce this error

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 :wink:

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

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

···

--
John Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

On Wed, Jun 8, 2011 at 09:16, Steve Klabnik <steve@steveklabnik.com> wrote:

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

Oh you are a clever one :wink:

···

On Jun 8, 9:16 am, Steve Klabnik <st...@steveklabnik.com> wrote:

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

Doesn't give the right result. You want raise, not throw.

···

On Wed, Jun 8, 2011 at 6:16 AM, Steve Klabnik <steve@steveklabnik.com> wrote:

throw NameError.new("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

···

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:

$ 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

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:

$ 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

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

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
adgar@carboni.ca
http://carboni.ca/

···

On Jun 8, 2011, at 10:56 AM, Christopher Dicely wrote:

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.

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:

Interesting. What platform on you on?

···

On Jun 8, 10:59 am, Michael Edgar <ad...@carboni.ca> wrote:

On Jun 8, 2011, at 10:56 AM, Christopher Dicely wrote:

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

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

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.

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
adgar@carboni.ca
http://carboni.ca/

···

On Wed, Jun 8, 2011 at 7:59 AM, Michael Edgar <adgar@carboni.ca> wrote:

On Jun 8, 2011, at 10:56 AM, Christopher Dicely 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:

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.

···

On Jun 8, 11:28 am, Intransition <transf...@gmail.com> wrote:

Interesting. What platform on you on?

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
adgar@carboni.ca
http://carboni.ca/

···

On Jun 8, 2011, at 11:28 AM, Intransition wrote:

On Jun 8, 10:59 am, Michael Edgar <ad...@carboni.ca> wrote:

On Jun 8, 2011, at 10:56 AM, Christopher Dicely wrote:

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.

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

Interesting. What platform on you on?

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.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

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?

···

--
John Feminella
Principal Consultant, BitsBuilder
LI: http://www.linkedin.com/in/johnxf
SO: User John Feminella - Stack Overflow

... 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
adgar@carboni.ca
http://carboni.ca/

···

On Jun 8, 2011, at 12:19 PM, Chad Perrin wrote:

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.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

Wow. Um. Sorry. I mangled the grammar of that sentence. It should
have read as follows:

    It works in 1.8.7, 1.9.1, and 1.9.2 for me.

···

On Thu, Jun 09, 2011 at 01:19:25AM +0900, Chad Perrin wrote:

It works the same both 1.8.7, 1.9.1, and 1.9.2 for me.

--
Chad Perrin [ original content licensed OWL: http://owl.apotheon.org ]

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?