I was experimenting with Enumerable and Comparable. I read the documentation and wanted to try it out.
class Apple
attr_accessor :color
end
class Fruit
include Enumerable
include Comparable
attr_accessor :apples
def initialize
@apples = []
end
def <=> o
@apple.color <=> o.color
end
def each
@apples.each {|apple| yield apple }
end
def to_s
"apple: #{@apple.color}"
end
end
fruit = Fruit.new
a1 = Apple.new
a1.color = :red
a2 = Apple.new
a2.color = :green
a3 = Apple.new
a3.color = :yellow
fruit.apples.push a1
fruit.apples.push a2
fruit.apples.push a3
Two things are not working as expected. So I override to_s, I expect each index of array to contain a string like "apple: red". Instead I get this:
fruit.sort
=> [#<Apple:0x007fbf53971048 @apples=[], @color=:green>, #<Apple:0x007fbf53999890 @apples=[], @color=:red>, #<Apple:0x007fbf5409b530 @apples=[], @color=:yellow>]
Second issue is when I include Enumerable, the instance methods of Enumerable should have been added to the ancestor chain right before the inherited classes. This should have included methods of Enumerable like with_each, reduce, etc to the ancestor chain. However, when I do this:
fruit.each.with_index(1).reduce({}) do |acc,(apple,i)|
acc << { i => apple.color}
end
LocalJumpError: no block given (yield)
as you can see, I get a LocalJumpError. I expected a result like this:
{ 1 => :red, 2 => :green, 3 => :yellow}
What am I doing wrong? I defined each like I was supposed to yet it doesn't work as expected.