Block Behavior:
def method_that_takes_a_block
yield
puts "this happened in the method"
end
method_that_takes_a_block do
puts "this happened in the block"
end
# => this happened in the block
# => this happened in the method
# yield should be protected by block_given?
# in case the caller does not provide a block
method_that_takes_a_block
# => no block given (yield) (LocalJumpError)
def method_that_takes_a_block
if block_given?
yield
else
puts "No block provided!"
end
end
method_that_takes_a_block
# => No block provided!
Proc Behavior:
# defining a proc:
p = Proc.new { puts "I'm a proc!" }
# or this:
p = proc { puts "I'm a proc!" }
# calling a proc
p.call
# => I'm a proc!
# procs don't throw an error if passed arguments
# don't match method signature
p.call(1, 2, 3)
# => I'm a proc!
p = Proc.new { |name| puts "Hello, #{name}" }
p.call
# => Hello,
p.call("Jake")
# => Hello, Jake
# In a proc 'return' returns from it's calling context
p = Proc.new { return nil }
p.call
# unexpected return (LocalJumpError)
def proc_in_a_method
p = proc { return "returning from the proc" }
p.call
return "returning from the method"
end
puts proc_in_a_method
# => returning from the proc
Lambda behavior:
# similar to procs, but defined using 'lambda' or '->'
l = lambda { puts "I'm a lambda" }
l.call
# => I'm a lambda
l = -> { puts "Different way to declare a lambda" }
l.call
# => Different way to declare a lambda
# passed arguments must match method signature:
l = lambda { |name| puts "Hello, #{name}" }
l.call
# wrong number of arguments (given 0, expected 1) (ArgumentError)
l.call "Jake"
# => Hello, Jake
# In a lambda 'return' only returns from the lambda
def returning_from_a_lambda(n)
is_even = lambda { |n| return n % 2 == 0 }
if is_even.call(n)
puts "#{n} is even"
else
puts "#{n} is odd"
end
end
returning_from_a_lambda 1
# => 1 is odd
returning_from_a_lambda 2
# => 2 is even