libik
libik

Reputation: 23029

Returning Enumerator in own each method

I have class with this method, which should return Enumerator, if no block is given or enumerate if it is given. It is just simulation of Array.each method. Enumeration is working properly.

  def each
    if (block_given?)
      0.upto(size - 1) do |x|
        yield @data[x]
      end
    end
  end

And it is tested wit this code :

it "should return Enumerator" do
  res = subject.each
  res.class.should eq Enumerator
  res.to_a.should eq data
end

The error is "Failure/Error: res.class.should eq Enumerator"

It is FORBIDDEN to use @data.each (or collect, map, etc.), I have to implement it myself. I have spent about two hours on the internet and I still dont get how to do it, because in every example, they just delegate "each" function to already finished class like Array... Or they just dont care about returning "Enumerator" for no block given.


SOLUTION :

  def each
    if (block_given?)
      0.upto(size - 1) do |x|
        yield @data[x]
      end
      self
    else
      to_enum(:each)
    end
  end

Upvotes: 1

Views: 767

Answers (1)

Peter Alfvin
Peter Alfvin

Reputation: 29389

Your first issue is that you're not explicitly returning anything from your method. In the case that a block is passed, the convention for each is to return self, as Array does.

In the case that a block is not given, the standard way to create an Enumerator is with the Kernel#to_enum method. So, for example, you can use the following as the first line of your method, as recommended in What's the best way to return an Enumerator::Lazy when your class doesn't define #each?

return to_enum(:each) unless block_given?

Upvotes: 2

Related Questions