For example, arrays in ruby have a method called each (although technically it's an Enumerator, but think of it as basically a method for now). You can say:
a = [1,2,3]
a.each {|i| print i}
and ruby will output something like 123. The part inside the curly braces is a block. You can also have a block like this:
a.each do |i|
print i
end
and it's the same thing. A block is basically a group of statements.
Each is basically a function that can take a block. To make your own function that can take blocks, you use the yield statement. For example, say you have a function like this (copied from ruby docs page):
def three_times
yield
yield
yield
end
This yield statement is different in ruby than it is in, say python. Any function that has a yield statement inside it must take a block when it is called. You pass it a block by simply writing the block directly after the function call. Every time the execution in the function reaches a yield statement, the block is evaluated. So, writing three_times {print 'hello '} would output hello hello hello.
You can also pass values to the yield statement, like this:
def one_ten
for i in 1..10
yield i
end
end
To access the value passed to yield, you write a block with a variable name in vertical lines at the front, like this: one_ten {|i| print i} or:
one_ten do |i|
print i
end
Both of those will print 12345678910 to the output.
Here, we're really talking about iterators. Iterators are functions that have the yield statement in them, e.g. they can return one or more times with different values depending on how their yield statements are organized. In ruby, it seems that iterators are linked intrinsically to blocks.
One more thing. In python, for example, yield statements are sort of like return statements, but in ruby, yield statements actually evaluate to the last statement processed in the block. (Notice that technically, yield is not a statement, it's a function itself.) So you can have something like this, for example:
def counting_up
a = 0
while a <= 10
a = yield a
end
end
counting_up do |yielded|
print yielded
yielded + 1
end
So that's what blocks are in ruby, and how they're useful.
No comments:
Post a Comment