1

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)

2 Answers 2

3

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

0

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;
  if(current==0)
    yield return current++;
  (for byte i=2;i<128;i++) //Fibonacci numbers grow big quickly.
  {
    long tmp=current+previous;
    previous=current;
    current=tmp;
    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())
   {
     if(++currentCount<count)
       break;
     return value;
   }
}

Powerful stuff.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.