Proc and Lambda and Block (oh my)

Something neat about  ruby is the equivalence of procs, lambdas and blocks. Take a quick look here:

foo = Proc.new do |x|
puts "In a proc. X is valued at #{x}"
end
foo.call(24)
output -- "In a proc. X is valued at 24"

Pretty simple. Much like an UnboundMethod object, you have to call the proc with call. It can have variables supplied to it with the slide operator ||, or it can inherit the same from the surrounding scope:

x = 1
foo = Proc.new do
puts "In a proc. X is valued at #{x}"
x = 25
end
puts "#{x}"
-- outputs 25

A lambda is an alternative proc syntax. Instead of explicitly creating a proc object, you get an anonymous one still bound to a variable:

bar = lambda { |x| puts "In a lambda. X is valued at #{x}"}
bar.call(32)
--- output "In a lambda. X is valued at 32"

Now, let’s take a look at a block. First, we define a method that yields to a block:

def runnable
puts "Inside runnable."
yield
puts "Still inside runnable."
end

 

Now, we call the method with the same “do” keyword we already used for the proc:

runnable do
puts "I am a block."
end
--output: Inside runnable.
I am a block.
Still inside runnable.

Much as you can insert Proc.call anywhere inside a scope, so you can also insert yield inside a scope and define the proc on-the-fly in a block. Compare the syntax of yielding a variable to that of using a variable with a Proc:

def runnable
puts "Inside runnable."
yield(42)
puts "Still inside runnable."
end
runnable do |x|
puts "#{x}"
end
output -- 42

This allows an associated block to use a variable set within the method. What’s neat, though, is that we can see that the method that yields has a key difference to a Proc: it cannot see into the external scope:

x = 1
def runnable
puts "Inside runnable."
yield(x)
puts "Still inside runnable."
end
runnable do
puts "I am a block."
end
--output - this code fails with an error.

There’s a scope defined by the method, and the variable x is different inside that method than outside of it. 

All this is documented in a github repo: https://github.com/jamandbees/proclambda — feel free to look through the history and goof around.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s