My explanation of the Ruby block
I have been trying, for quite a while, to figure out a succinct way of defining what a block is in Ruby. For months a good explanation has eluded me and finally last night it came to me, like all good revelations; in the shower.
In my last post we looked at an example of using Event Listeners, which also made use of what I called an inline function. In actual fact, the true term for this is Anonymous Function. Let’s take another look at an Anonymous function to clarify (from “function” to the ending curly brace):
$$('a').each(function(element){
element.addClass('link');
});
As you can see, there is no name associated with the function, so you can’t call it from anywhere else in your code. Essentially, all it is giving us is the ability to process a block of code inside another function. And that, my friends, is a pretty accurate representation of a block in Ruby (from “do” to “end”):
['a', 'b', 'c'].each do |element| puts element end
In the JavaScript example we made an array of all the <a> objects on a page and processed an Anonymous Function for each object. In the Ruby example we took an array of strings (which are also objects by the way) and processed a block for each. While the two examples may have varied ways of representing the different syntactic elements (because they’re different languages; duh!), the structure is almost identical.
Blocks are a little more complex than that of course; this from the Pragmatic Programmers Guide:
a Ruby block is a way of grouping statements, but not in the conventional way.
First, a block may appear only in the source adjacent to a method call; the block is written starting on the same line as the method’s last parameter. Second, the code in the block is not executed at the time it is encountered. Instead, Ruby remembers the context in which the block appears (the local variables, the current object, and so on), and then enters the method. This is where the magic starts. Within the method, the block may be invoked, almost as if it were a method itself, using the
yieldstatement. Whenever ayieldis executed, it invokes the code in the block. When the block exits, control picks back up immediately after theyield.
I’m not sure the newbs out there are going to understand what the heck they’re on about, which is the reason I’ve been mulling over a short, to-the-point explanation for so long. So, to start with; try thinking of a block like an Anonymous Function and you’ll start to see the beauty of the block!