Tuesday, 18 September 2007

Even More Ruby Surprises - Blocks and Closures 101

For me, the Ruby learning continues apace. This weekend it was the turn of blocks and closures, however first I'd like to mention a little pecadillo which made me smile.

Surprise C1 - Parallel Assignment

Now those Ruby folks constantly bang on about how expressive Ruby is and generally then go off into very complicated and convoluted discussions as to why, but this, to me is a perfect illustration:

What this says to me is "I have some variables. I want to call them this and this, and I want them to equal this and this." Simple and legible. Nice

Surprise C2 - Blocks Can Have (Multiple) Parameters Passed to Them and Can Return Values Too

Now coming from a Java background, the whole concept of blocks and closures was a bit of a mystery to me. (Now I do get anonymous inner classes, but frankly the whole Closures debate had me a little confused.) No longer. After a single paragraph in the PickAxe (which I won't restate here, suffice to say you should buy the book) I now see what they're all about and how damn useful they can be. I can also see how useful passing a parameter to a block can be:

And if we combine this with the ability to return a value from a block too:

And how about multiple paramaters? Easy:

All in all, blocks seem really controllable and intuitive (to me at least).

Surprise C3 - Ruby Functions Can React According to Whether They Were Called With a Block or Not

It gets even better. Ruby also allows you to simply code functions which can be called with blocks as well as without. If you call with a block, they can react in their own special way:

Surprise C4 - Ruby Blocks Can Be Closures

What we've seen so far haven't strictly speaking been closures. However, Ruby does allow you to use blocks in such a way that they are - blocks can be passed as arguments, and then assigned to variables as Proc objects, and then exceuted using the Proc#call method. To seal the deal, Ruby makes sure that it remembers the context in which a block was defined. That is to say the value of "self", plus the methods, variables and constants in scope. Behold:

Netbeans 6 Note: The grey squiggles under the start_button and pause_button variables indicates that they have been initialised, but not yet used. Handy eh?

Hasta luego!

No comments: