← Back to Ruby Operators

Block Argument

The & symbol is used to denote a block argument in a method definition.

def each_with_index(&block)
  ...
end

Fetch as an example

Let's look at a practical example by reimplementing part of #fetch.

The #fetch method will try to grab a value from a hash using the key. We can optionally include a block argument which will be called on a miss.

h = { "a" => 100, "b" => 200 }
h.fetch("a")                            #=> 100
h.fetch("z", "go fish")                 #=> "go fish"
h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"

A simplified version of #fetch might look like this:

def fetch(key, default = nil, &block)
  if has_key?(key)
    self[key]
  elsif block_given?
    yield key
  elsif default
    default
  else
    raise KeyError, "key not found: #{key.inspect}"
  end
end

If we have the block argument (block_given?) and the key isn't present (self.has_key?), we call the block with the key.

Forwarding a block argument

Here is another example where you can see the block argument alongside the positional and keyword arguments.

def forwarding_method(*x, **y, &block)
  target_method(*x, **y, &block)
end

Note: if you're doing something like the above block, you may be interested in the Argument Forwarding syntax.

References