Adding some print statements in the inject helps trace what is 
happening. Starting with Sam's code:

class Items
...
   def price
     @items.inject do |a,b|
       puts "a = #{a} of class #{a.class}, b = #{b} of class #{b.class}"
       a+b
     end
   end
end

I also added a to_s method on Item:

class Item
...
   def to_s
     "Item #{@name} costs #{@price}"
   end
end

The output is:

a = Item a costs 1 of class Item, b = Item b costs 2 of class Item
a = 3 of class Fixnum, b = Item c costs 3 of class Item
6

The first argument to the inject block ('a') is the accumulated value. 
Initially, this value is set as the first item in the array, so in the 
first line we add two 'Item' instances.  The return value of the first 
addition is a number, so that partial sum is used in the second line: 
now we are adding a 'Fixnum' to an 'Item'.  Sam's coerce solution makes 
this addition work.

A different approach is to make the function used in inject add up _and 
return_ objects of the same type.  So the + method on the Item class 
would return an instance of Item:

class Item
...
   def + item
     Item.new("acc", @price + item.price)
   end
end

The output now shows only Item instances are being passed around:

a = Item a costs 1 of class Item, b = Item b costs 2 of class Item
a = Item acc costs 3 of class Item, b = Item c costs 3 of class Item
Item acc costs 6

This way, you don't need the 'coerce' or 'respond_to?' methods.  You
might want to alter the Items#price method to return the final sum only:

class Items
...
   def price
     @items.inject(:+).price  # return the 'price' of result
   end
end

-- 
Posted via http://www.ruby-forum.com/.