By hakunin on July 16, 2009
Today I had to silence some output streams so that messages don’t pollute the STDOUT. I used the silence_stream method built into Rails, described well in this article.
silence_stream(STDOUT) do
# ...my code...
end
Very nice, except I also wanted to filter STDERR output. Not a problem.
silence_stream(STDOUT, STDERR) do
# ...my code...
end
Well, shit. Here I got a “too many arguments” error. So it doesn’t support multiple streams. I guess it wants me to be ugly.
silence_stream(STDOUT) do
silence_stream(STDERR) do
# ...my code...
end
end
I personally don’t take kindly this level of suckiness around here. I want example #2 to work. Well, after lighting some candles and praying to the Ruby gods, I came up with a scary implementation. In fact it’s so spooky that it may have the same effect as glancing at the Mexican Starting Frog of Southern Sri Lanka. You may then throw a chair at me on the Jerry Springer show, so I rather not show it to you.
However, after having cleansed my .rb file with some broc flowers and xander roots I came up with a better solution. Recursion is the key. See if you can understand what is happening.
def silence_streams(*streams, &blk)
silence_stream(streams.pop) do
if streams.empty?
yield
else
silence_streams(*streams, &blk)
end
end
end
This is a basic use of recursion, which is not immediately clear when dealing with nested Ruby blocks. When multiple streams are passed in I’m popping out the last stream and silencing it alone, then calling the same method with the remaining streams. This is happening until only one stream left to silence. The last one gets silenced with the original block passed in, which means that the original block is executed at the deepest nesting level, where all passed streams are silenced. As a result I got this much desired functionality without resorting to eval, yay.
silence_streams(STDOUT, STDERR) do
# ...my code...
end
There we go. This solution can be applied to cases where you’d rather avoid overriding stuff (thus keeping out of method implementation details).
Update: Made recursion more concise thanks to apeiros on #railsbridge.
Posted in rails, ruby, solutions
By hakunin on June 21, 2009
This tester_elf script is very dumb, which is uncharacteristic of elves in general. Why did I name it tester_elf? Well, it’s a Santa’s little helper type of elf as opposed to an individual of Tolkien’s highly cultural race. I do crave some nice D&D RPG experience but there aren’t any good new games in that direction. Everything gets dumbed down nowadays.
Anyhow, here’s the gist of it.
It just runs a test file every time you save it. Stupid but useful when autotest is too bulky. Instructions are in the gist.
Posted in rails, ruby, solutions
By hakunin on May 30, 2009
Please welcome a new thingie I just released – yui_compressor_fu.
Point
yui_compressor_fu delicately minifies all your assets (linked with javascript_include_tag, stylesheet_link_tag helpers) with YUI Compressor. It abides Rails caching rules. All you have to do is install the plugin, and minifying will automatically kick-in when rails performs its normal caching routines.
Tale
Today I was having my usual cup of Earl Grey with lemon while trying to find some JS/CSS minifying solution. Nowadays Rails provides built-in concatenation and caching, but not compression. I wanted to find something that transparently adds some minifying to the mix. Well, not so fast.
After flipping through quite a few choices, I wasn’t impressed at all. Available plugins either require too much configuration (why do I have to list all my assets again, asset_packager?) or they use inferior compression algorithms (Packer/MinJS). According to my research (don’t quote me) – YUI Compressor kicks some major ass. A few minutes of fruitless digging later I decided to make this plugin instead.
Feel free to try it out and let me know of any issues you encounter.
Posted in rails, ruby, solutions