On 01/12/11 09:03, Sébastien M. wrote: > Hello, > > This is my first post, and i hope i use the correct topic. > There are two errors i do not understand in the code below > > I've commented out the line that don't work, and the line directly below > works just fine > Finally i put the errors when using the problematic lines > > I do not see any errors in the commented line, if someone do i'll be > happy to understand what is wrong > > thx in advance > > Here is the code > ---------------------------------------------------------------- > class Item > attr_reader :name, :price > > def initialize name, price > @name, @price = name, price > end > > def + item > # price + item.price if item.respond_to? price #### 1 > price + item.price if item.is_a? Item > end > end > > class Items > def initialize > @items = [] > end > > def<< item > @items<< item if item.is_a? Item > end > > def price > @items.collect { |i| i.price }.inject(:+) > # @items.inject(:+) #### 2 > end > end > > i = Items.new > > i<< Item.new('a', 1) > i<< Item.new('b', 2) > i<< Item.new('c', 3) > > puts i.price > -------------------------------------------------------------- > The errors > -------------------------------------------------------------- > ##### 1 > ./test2.rb:11:in `respond_to?': 1 is not a symbol (TypeError) > ##### 2 > ./test2.rb:25:in `+': Item can't be coerced into Fixnum (TypeError) > The first error is pretty straight forward to sort out. The #respond_to? method is expecting a symbol, so changing 'price' to ':price' fixes that. The other error is due (I believe) to the fact that the inject ends up trying to use Numeric#+ instead of your Item#+ method when the object on the left of the operator is a number. To fix this you can define Item#coerce. This is likely not the best way to do it, but it appears to work; class Item attr_reader :name, :price def initialize name, price @name, @price = name, price end def coerce arg if arg.is_a? Numeric [arg, price] end end def + item price + item.price if item.respond_to? :price end end class Items def initialize @items = [] end def << item @items << item if item.is_a? Item end def price @items.inject(:+) end end i = Items.new i << Item.new('a', 1) i << Item.new('b', 2) i << Item.new('c', 3) puts i.price Hope that helps Sam