It’s a good illustration of this standard unix solution, that most Ruby developers have (I’m 100% sure) never heard of. It assumes you know something about Ruby, and that’s about it.
Background: If you’re not running a Rails/Ruby based web-app with bundler and a non-root user (the most common bundler setup), this article is no help for you.
We’ve all been there. Suddenly, for no apparent reason, your web app is performing like shit, and you don’t know why. All your logging is for naught, and you need to profile your code. And for whatever reason, you have to do it in production.
You google, as we all would. You find rack-perftools_profiller. It sounds awesome, so you try it.
After 4 hours of trying to get bundler to install the damn thing, you give up and light your data center on fire.
TOO BAD YOU DIDN’T READ THIS FIRST.
You have to install the perftools.rb (which the rack-perftools_profiler gem users) gem as a system gem first.
sudo gem install perftools.rb
After this, your deploy and `bundle install` will go fine.
Why, you ask?
Well. You see, when bundler installs a gem that needs a C library compiled, it doesn’t provide the proper ruby env (the env that bundler makes for all the things run in it) to the building process.
That normally doesn’t matter, but in this case, it does. perftools.rb requires some ruby headers that are not installed with the normal “make install”. In order to install them, it usse another gem “ruby_core_source” to fetch and extract them.
Now, ruby_core_source is run from within the C extension building process, which, you’ll recall, doesn’t have the bundler evn setup, and so it doesn’t know where it really should pull the headers to, so it tries to write them to /usr/share/something/something_else. Which fails, and the process bombs.
Now, there’s a patch to ruby_core_source that fixes this. But it’s not released as a gem you. You may try to circumvent this (as I did) by installed it via bundler, using the :git => “” option. This also fails, as the building process doesn’t get the bundler env, and has no idea about the installed “good” version.
Installing perftools.rb as root fixes all that, as it lets ruby_core_source install the headers to the system, where perftools.rb can then find them. Even if you have bundler setup to ignore system gems, the header files are already there, so perftools.rb just builds.
I hope I saved you hours of digging.
We’ve all been there. Gigantic XML file in need of parsing, regular DOM parsing exploderates RAM usage beyond any hope of completion, contemplating writing a SAX parser, and suicide.
Before you solve your XML parsing woes permanently, take a look at SAXMachine. It’s a Ruby DSL for SAX parsers. It’s built on top of Nokogiri, which is already stupid fast and easy, and it makes writing a SAX parser so much easier.
I’m not going to give you an example, the README from the above link does a good enough job explaining. For me, it took what had promised to be a multi-days long code spelunking odyssey and turned it into a few hour long errand. Bliss.
Just go read about it.
So, you have fancy spiffy code. It looks kinda like this:
It works great on your local machine, doing what you need.
Then, you deploy. And the world ends. It ends, not in fire, or water, but a LocalJumpError, like so
“WTF?” you think.
Check your Ruby versions. I bet production is 1.8.6 and your local machine in 1.8.7. Naughty.
1.8.7 will implicitly do a .to_a right before the inject. 1.8.6 does *not*.
Here’s how to make it work in both:
Nothing. I didn’t learn anything in this chapter, which was a well-written look at method_missing and define_method. Good info, just not new to me.
Mostly overview, for me at least. Learned that Ruby creates an anonymous class for each module in the inheritance chain though, so the “ancestors” return includes them. Neat-o.