Code Snippets
/

Blocks, Procs, and Lambdas

Blocks, Procs, and Lambdas

Ruby has three closely related callable forms: blocks (one-shot, attached to a method call), `Proc` objects (named, non-strict about arity), and `Lambda` objects (named, strict about arity and `return` semantics). This snippet shows how each is constructed, when `yield` versus `&block` is appropriate, and the subtle differences in `return` and arity checking that decide which to use.

Ruby
Medium
3 snippets
ruby-blocks
ruby-yield
ruby-procs-lambdas
functional-programming

801 views

4

# A block is the do/end or {} attached to a method call.
# Inside the method, `yield` invokes it. `block_given?` checks for one.
def each_squared(arr)
  return enum_for(:each_squared, arr) unless block_given?
  arr.each do |n|
    yield n * n
  end
end

each_squared([1, 2, 3]) { |sq| puts "square=#{sq}" }

# Without a block, the method returns an Enumerator (chainable).
squared_enum = each_squared([4, 5, 6])
p squared_enum.to_a # [16, 25, 36]

Every Ruby method can implicitly accept ONE block; you do not declare it in the parameter list. Inside the method body, yield value calls the block with value; block_given? lets you behave differently when the caller did not pass one. Returning enum_for(:method_name, ...) when there is no block is the canonical pattern: it lets callers either consume the iterator inline OR get back an Enumerator they can chain with .lazy.map.first(...). This is exactly how built-in methods like Array#map behave.