Rails: When an Uninitialized Constant Hits the Vent
Posted: January 29th, 2008 | Filed under: Programming | Tags: constant, Programming, rails, ruby, tip, uninitialized | 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:
... 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.
/my_module
klass1.rb
...
utils.rb
/utils
net_session.rb
The piece of code in klass1 that failed looks as follows:
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.
The Ruby on Rails addict, industrial photographer and amateur electronic music composer. In the mean time I build great web applications, contribute to OSS and help AVAAZ to save Great Barrier Reef.
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.
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!
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.
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
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
Excellent site, keep up the good work
There is obviously a lot to know about this. There are some good points here.