Block Object
In this chapter, you will learn about block objects and delayed execution of the code in a block object.
What is a Block?
A block is a chunk of code that is enclosed between the curly braces or do-end. Let's create a simple block that prints hi.
{ puts 'hi' }
If you run this program, you will get the error:
syntax error, unexpected tSTRING_BEG, expecting keyword_do or '{' or '('
We enclosed a chunk of code using the curly braces, but, it is not valid syntax in Ruby.
Converting a Block into an Object
We can use Proc, lambda or the literal constructor -> to convert a block into an Object.
-> { puts 'hi' }
If you run this program, you will not get any syntax error. But, it will not print anything to the standard output.
Delayed Execution
Why did not print hi? If you had written:
puts 'hi'
Running this will print hi. What is the difference? We converted the block into an object. What is this object? Let's find out.
p -> { puts 'hi' }
This prints:
#<Proc:0x007fb1f0@untitled 2:16 (lambda)>
The output shows the memory location of the Proc object, but it also has lambda. Let's make the output easy to read. We can check the class of the returned Proc object.
greet = -> { puts 'hi' }
puts greet.class
We assigned the value returned after conversion to a variable. Then, we print the class of that object. This prints:
Proc
Now we know that using the literal constructor created a Proc object. We can execute the code by sending a call message to the Proc object.
greet = -> { puts 'hi' }
greet.call
This prints:
hi
This is how block objects exhibit delayed execution by nature. The above example is equal to this:
def greet
puts 'hi'
end
greet
This version of the example has a name for the method that we can call, the greet method. The Proc version of the example has no name for the method. The block we converted into an object is an anonymous function. It has no name. The greet variable is a pointer to an anonymous function. We call the anonymous function by sending call message to it.
Fabio Asks
Why do we need to assign the Proc object to a variable?
Why not just do this:
-> { puts 'hi' }.call
Yes, this will work. We are calling the anonymous function by sending the call message to it. In this case, we are not taking advantage of delayed execution that block objects provide us.
Rhonda Asks
What is the advantage of assigning it to a variable?
Methods can take this proc object as an argument and execute them by sending the call message. Thus, the code can be re-used in different scenarios.
Summary
In this chapter, you learned how to convert a block into an object and delayed execution of the code in a block object.