liveBook · Manning

Return value

As explained in The Well-Grounded Rubyist, Fourth Edition

A return value is the value produced by evaluating a Ruby method call, implicitly taken from the method's last evaluated expression unless execution returns earlier.

A method call has a value

Suppose `c2f` converts Celsius to Fahrenheit. Calling `obj.c2f(100)` evaluates to `212`: the method call is an expression, and `212` is its return value. The calculation is the method’s only expression, so its value becomes the value of the call. section 2.1.4

A Ruby method normally returns the value of the last expression evaluated while it runs. You can write `return c * 9.0 / 5 + 32` to make that result explicit, but `return` is usually optional. It is needed to leave a method early. An empty method still returns a value: `nil`. section 2.1.4

The value a call returns is useful in several ways:

  • A query method can return an instance variable. For example, a `venue` method whose body is `@venue` hands that value back to its caller. section 3.2.1
  • A returned value can become part of another expression. Calls such as `ticket.event` and `ticket.venue` supply details for a printed ticket summary. section 2.2.2
  • To return several values, use `return a,b,c`, which wraps them in an array, or make the array explicit with `[a,b,c]`. section 2.1.4

With a block, keep two directions of value flow separate. `5.times` yields to its block five times, offering iteration values from `0` through `4`, but the completed method call returns `5` once. Likewise, `each` yields collection elements yet returns its original array when given a block. Lines printed by a block are output, not the method’s return value. section 6.3.5 section 6.3.6

`map` makes the block’s return values central. It yields each array element, collects the value returned by each block execution, and returns a new array of those results. Thus `names.map {|name| name.upcase }` returns an array of uppercase names rather than the original array. section 6.3.7

class Array
  def my_map
    c = 0
    acc = []            #1
    until c == size
      acc << yield(self[c])          #2
      c += 1
    end
    acc                #3
  end
end

The `my_map` implementation shows both value flows: `yield(self[c])` receives each block result into `acc`, and the final `acc` expression becomes the method’s return value. section 6.3.7

How The Well-Grounded Rubyist, Fourth Edition covers it

How deep it goes
Explains implicit and explicit returns, early exit, empty methods, multiple values, and the distinction between block results and method results.
Examples
Uses temperature conversion, ticket queries, irb iteration output, and a hand-built map accumulator.
What you can do after
Build it from scratch: implement a map-like method that collects block results and returns the resulting array.
How it connects
Links expression evaluation and instance variables to method calls, then distinguishes block yielding from the return behavior of times, each, and map.

Also explained in

Compare how 8 books explain return value →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of The Well-Grounded Rubyist, Fourth Edition. The section links point to the parts of the book it draws on.