you know methods. methods can bind names to arguments, like so:
def times_two(x)
x * 2
end
times_two(4)
# => 8
in this example, x
is a named argument, and the value 4
is provided as a concrete parameter.
let's do the same thing again, but without using methods:
times_two = Proc.new { |x| x * 2 }
times_two.call(4)
# => 8
self-explanatory? cool.
it also works without the naming:
Proc.new { |x| x * 2 }.call(4)
# => 8
def with_product(a, b, &block)
block.call(a * b)
end
with_product(4, 2) { |a_times_b| 2 * a_times_b }
# => 16
when we call the method with_product
, we provide three parameters: 4
, 2
, and a block that takes one argument and binds it to the name a_times_b
. the method with_product
calls the block with a * b
. inside of the block, the result of that gets the name a_times_b
, and the block can do with it whatever it wants.
def with_product(a, b)
yield(a * b)
end
with_product(4, 2) { |product| 2 * product }
# => 16
this example is equivalent with the previous one. the difference is really just the syntax. every method is able to take a block parameter, even without listing it explicitly. when you do that, you don't have a name for the block that you could use to call/execute it. that's why yield
exists. it allows you to call a block argument that doesn't have a name.
really understandable! I like how when I read it if feels like someone is talking to me with all the "you"s. I added one more example for a different syntax under stand-alone blocks = procs, because it was listed earlier in this book that i'm following along with. it looks like such:
The only other thing I wanted to point out is that this phrase is structured very german: "and the block can do with it whatever it wants."
In english it's still correct but it sounds kinda funny. "The block can do whatever it wants with it" is the less german way to say it. haha.
THANKS!