Take the 2-minute tour ×

I've been reading over the Enumerable module in Ruby, and it contains a few methods that follow the pattern of

enum.foo(n) {|obj| block } → nil
enum.foo(n) → an_enumerator

Which is to say, they seem to return an iterator when chained and nothing otherwise. What's the reasoning behind taking this approach instead of just returning a sequence? (I'm asking about general reasoning for this approach, not necessarily just its use in Ruby)

share|improve this question
add comment

2 Answers

up vote 2 down vote accepted

I think it was introduced to better support chaining of operations. It can be too expensive to generate unnecessary intermediate objects.

See for example https://github.com/rdp/ruby_tutorials_core/wiki/enumerator

share|improve this answer
add comment

So I'm not sure of the differences between the two approaches in Ruby but in C# we have the yield keyword (that can only be used when returning IEnumerable or IEnumerable (the generic Enumerable). What the yield keyword does is create a closure over the current environment creating an enumerator that uses that closure. It's easier to demonstrate in code than talk about it. Here is a Fibonnaci generator using yield:

public IEnumerable<long> Fibonnaci()
  long current, previous;
    yield return current++;
  (for byte i=2;i<128;i++) //Fibonacci numbers grow big quickly.
    long tmp=current+previous;
    yield return tmp;

Note that I don't have to use recursion, I just evaluate my current value and return. Now if I want to get the xth Fibonnaci number I just create a function like so:

public long GetFibonacciNumber(byte count)
   byte currentCount;
   foreach(long value in Fibonacci())
     return value;

Powerful stuff.

share|improve this answer
add comment

Your Answer


