Exploring blocks in ruby
29 Jan 2015Ruby has a very cool feature called code blocks. Sometimes referred to as closures, code blocks are custom pieces (or blocks) of ruby code that you specify to functions that inject your code block whenever the yield
keyword is used.
In today’s post, I’m just going to present a simple example and usage.
Source data
The example we’re going to use will be a Manager to Employee style relationship. A Person
class is going to manage an array of Person
objects that we’ll classify as staff for that person. Here’s the class definition:
So a Person
will have a name
, position
and staff
. Some sample data using this structure might look as follows:
Simple example
mary
is the manager for joe
and bob
. Using the Array
function each
, we can use a code block to present each person to screen:
That’s our first code block. each
will run our code block for every Person
in mary’s staff
array.
Another level
If we introduce ‘bill’ as the manager of the company:
We can use each
to look at Bill’s staff, which is just Mary at this stage. More interestingly, we could implement our own function on the Person
class that shows all of that person’s descendants.
We’re going to call any code block specified to our descendants
function for each of the staff that are managed by this Person
object, but we’re also going to call each descendant’s descendants
function so that we recurse down the tree.
We could augment this call slightly to also include the manager of the descendants:
This will supply a manager to the calling block, 1 level down from where we specify.
This code here emits the following:
Mary’s manager variable in the block comes through as nil
as she’s a direct descendant of bill
, so we handle this case in the block as opposed to in descendants
.
You can specify as many parameters as you want in your yield
. It’s your block’s responsibility to do something useful with them!
Other options
Within your function, you can test the block_given?
property for a boolean that will determine if the calling code did or didn’t specify a block.
You can also have a parameter specified in your function &block
which can be handy should you need to pass the block around.