Content | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11

Official Ruby FAQ

If you wish to report errors or suggest improvements for this FAQ, please go to our GitHub repository and open an issue or pull request.

Other features

What does a ? b : c mean?

This is the so-called “ternary operator” and is the same as saying if a then b else c end.

How can I count the number of lines in a file?

The following code may give the fastest result.

File.readlines("example").size  # => 3

What do MatchData#begin and MatchData#end return?

They act with $~, and return the start index and the end index of the matched data in the original string. See an example in tab expansion.

How can I sum the elements in an array?

This section or parts of it might be out-dated or in need of confirmation.

Rather than solve the specific problem, let’s solve the general case. The first thing we will do is produce a method that will iterate over an Enumerable object and collect a single result. Smalltalk calls that method inject, so we will too:

module Enumerable

  # inject(n) {|n, i| ...}
  def inject(n)
    each {|i| n = yield(n, i) }

    n
  end
end

Notice how we have added the method to Enumerable. This means that anything that includes Enumerable can now use inject. But how do we use it? It takes a single argument n and a block. For each element in the thing being enumerated, it calls the block, passing in n and the element itself. The result of the block is assigned back to n. So, to define sum, we could write:

module Enumerable
  def sum
    inject(0) {|n, i| n + i }
  end
end

[1,3,5,7,9].sum  # => 25
(1..100).sum     # => 5050

How can I use continuations?

This section or parts of it might be out-dated or in need of confirmation.

Ruby’s continuations allow you to create an object representing a place in a Ruby program, and then return to that place at any time (even if it has apparently gone out of scope). Continuations can be used to implement complex control structures, but are typically more useful as ways of confusing people.

In [ruby-talk:4482], Jim Weirich posted the following examples of continuations:

# --------------------------------------------------------------------
# Simple Producer/Consumer
# --------------------------------------------------------------------
# Connect a simple counting task and a printing task together using
# continuations.
#
# Usage:  count(limit)

def count_task(count, consumer)
  (1..count).each do |i|
    callcc {|cc| consumer.call cc, i }
  end
  nil
end

def print_task()
  producer, i = callcc { |cc| return cc }
  print "#{i} "
  callcc { |cc| producer.call }
end

def count(limit)
  count_task(limit, print_task())
  print "\n"
end
# --------------------------------------------------------------------
# Filtering Out Multiples of a Given Number
# --------------------------------------------------------------------
# Create a filter that is both a consumer and producer. Insert it
# between the counting task and the printing task.
#
# Usage:  omit(2, limit)

def filter_task(factor, consumer)
  producer, i = callcc { |cc| return cc }
  if (i%factor) != 0 then
    callcc { |cc| consumer.call cc, i }
  end
  producer.call
end

def omit(factor, limit)
  printer = print_task()
  filter = filter_task(factor, printer)
  count_task(limit, filter)
  print "\n"
end
# --------------------------------------------------------------------
# Prime Number Generator
# --------------------------------------------------------------------
# Create a prime number generator. When a new prime number is
# discovered, dynamically add a new multiple filter to the chain of
# producers and consumers.
#
# Usage:  primes(limit)

def prime_task(consumer)
  producer, i = callcc { |cc| return cc }
  if i >= 2 then
    callcc { |cc| consumer.call cc, i }
    consumer = filter_task(i, consumer)
  end
  producer.call
end

def primes(limit)
  printer = print_task()
  primes = prime_task(printer)
  count_task(limit, primes)
  print "\n"
end