Reputation: 23029
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
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