Go! Go! Go!
I remember starting my journey with Ruby and seeing some code that looked a bit like this:
3.times { puts "Go!" }
Still today I look at the code and marvel at it. You know exactly what it's going to do.
And yet in less than 20 chars, there's so much more joy to discover.
You'd be forgiven for glossing over the 3.times
and not giving it a second thought – assuming it to be some kind of special syntax.
But when you do take that pause, and recall that in Ruby everything is an object, you can reason that 3
is an object (it's an instance of Integer
) and therefore times
must be a method available to instances of Integer
.
And you can kinda prove that by rewriting the above in a (ridiculous) longer format where we find the method times
on the instance of 3 and then call
that method.
3.method(:times).call { puts "Go!" }
What's interesting about that verbose format, though, is the documentation for times
becomes even clearer.
Calls the given block self times with each integer in (0..self-1)
Given that self
is 3, and our verbose code actually uses the method call
, we can be sure that { puts "Go!" }
is the given block.
And what's a block? Well, it's just a block of code. Everything inside those curly braces is just ... more Ruby.
Blocks don't need a name, nor do they need to be defined or registered anywhere else.
When you pass this block of code as an argument to the times
method, you are supplying the behaviour. (As opposed to supplying data, and letting the method define the behaviour.)
And times
is totally cool with this kind of arrangement. It has no desire to do anything other than perform what you say a certain number of times.