Avoiding nested blocks

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.

Dumb tester_elf

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.

yui_compressor_fu

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.