NR Time - Powerful time tracker for Mac OS X

Feel the ease of time tracking with NR Time. Log your time expenses in the billing-friendly format with minimal effort.

Rails: When an Uninitialized Constant Hits the Vent

Posted: January 29th, 2008 | Filed under: Programming | Tags: , , , , , | 7 Comments »

Last two weeks I was seeing the production server of one of my clients hit the same error over and over with no visible pattern. This second it works, the next it fails and leaves the Mongrel cluster in an undefined state somewhere between this world and hell.

The error I’m referring to is:

NameError (uninitialized constant MyModule::Utils::NetSession)
... backtrace follows ...

I need to repeat that it comes and goes under some non-obvious circumstances, and is hard to recreate. Fortunately, I found the solution and here’s what it was.

I have a directory hierarchy like below. I’m sure when you see it, it all becomes obvious and simple, but it wasn’t for me at that time as there were many files that I omitted below.

/lib
  /my_module
    klass1.rb
    ...
    utils.rb
  /utils
    net_session.rb

The piece of code in klass1 that failed looks as follows:

def new_session
  Utils::NetSession.new
end

Simple, heh.

Utils.rb is a helper module which is included into MyModule, but apparently loaded only when really necessary (it’s the only explanation why it didn’t fail all the time, as you will see). When it is loaded and included, the MyModule::Utils becomes defined, and Utils::NetSession resolution starts to fail. It happens as Rails begins looking for Utils name space from MyModule, finds MyModule::Utils and doesn’t find any NetSession there. That’s pretty much all to it.

The solutions are:

  • Either rename utils.rb (which I did in favor of utilities.rb), or
  • Use “::Utils::NetSession.new” (which is not safe as one day you can forget about the leading “::”, and get back to roots)

Hope this helps someone like me fighting the way through these extremely infrequent but painful Rails gotchas.


7 Comments

  1. 1 dashin said at 10:13 on March 24th, 2008:

    Hi, Alexey!

    As I can see you’ve faced with RoR much later than with Java, so the Grails framewok could be interesting for you because it has RoR ideology, and you can stil use your Java code with it.

  2. 2 Aleksey Gureev said at 10:38 on March 24th, 2008:

    Correct. I tried to start with Grails / Groovy several times, but each time it looked more like a kludge to me or an effort to reproduce what Rails already has. It looks like the developers who are bound to use Java in their organizations look for the way to make it as Rails as possible.

    Personally, I don’t see any reason to step on my throat and force myself into using these frameworks if I can do Rails. I mean, why? Just to be on the Java side or because I spent more than 7 years programming on it? I’m not bound by corporate obligations and regulations, and I choose whatever works best for me and aids my freelancing business — that’s the essence of being pragmatic programmer, by the way.

    I don’t value my past achievements as much as I do the opportunities. If new approaches and technologies overpass the past, it makes it even better and far more fun.

    Downloading your presentation on Grails now to see your position better…

    Thanks for the comment!

  3. 3 James said at 03:46 on June 11th, 2008:

    Thanks, I had a similar problem.

    I often need to specify the root class (leading ‘::’ thing), so I’m happy with that. But, a couple of my controllers had the leading ‘::’ specified in my routes file. There was no good reason for this, it didn’t cause any problems on the dev server – but did cause intermittent “unitialized constant” errors on the production server.

    The fix was to remove the leading :: in the config/routes.rb file.

    Again, I had similar sub-class hierarchies which seem to be conflicting, depending on when things were loaded.

  4. 4 lbunk said at 16:22 on August 20th, 2009:

    Thanks Aleksey – this post was helpful.

    My situation was that I had a model inheriting from a class inside the lib folder. Working fine in Mongrel but when starting the application in Passenger, it threw "uninitialized constant".

    I thought that the files inside the lib folder was automatically "added" but my solution was to require 'xx/xx' at the top of the model.

    Thanks,

    Lasse

  5. 5 lbunk said at 16:22 on August 20th, 2009:

    Thanks Aleksey – this post was helpful.
    My situation was that I had a model inheriting from a class inside the lib folder. Working fine in Mongrel but when starting the application in Passenger, it threw "uninitialized constant".
    I thought that the files inside the lib folder was automatically "added" but my solution was to require 'xx/xx' at the top of the model.
    Thanks,
    Lasse

  6. 6 Bill Bartmann said at 06:49 on September 2nd, 2009:

    Excellent site, keep up the good work

  7. 7 Manderson said at 10:50 on September 25th, 2009:

    There is obviously a lot to know about this. There are some good points here.


Leave a Reply