On 4/14/05, Mel Bohince <feet / att.net> wrote: > Really enjoying Ruby so far, but now I'm confused. To help learn Ruby, > I've been translating the Java code in the "Head First Design Patterns" > book into Ruby, aware that many are built-in with Ruby. While mimicking > the Decorator pattern I'm getting a strange failure to an assert_equal. > > The unit test excerpts: > @e = Expresso.new > @e.setSize('grande') > @e = Mocha.new(@e) > assert_equal(1.40, @e.cost(),"price check") --> pass > @e = Mocha.new(@e) > assert_equal("Expresso, Mocha, Mocha", @e.getDescription()) --> pass > #puts @e.cost() --> 1.6 ##sanity check, should be 1.00 + 0.20 + 0.20 + > 0.20 = 1.6 > ##### > assert_equal(1.6, @e.cost(),"price check2") --> fail with: > > 1) Failure: > testConcreteCondiment(TestBeverages) > [/Users/mel/Documents/Ruby_files/patterns/decorator/test/ > testbeverages.rb:70]: > price check2. > <1.6> expected but was > <1.6>. > 5 tests, 21 assertions, 1 failures, 0 errors > > Recreated in irb, the instance looks like: > => #<Mocha:0x7a884 @beverage=#<Mocha:0x21c94 > @beverage=#<Expresso:0x58310 @description="Expresso", @size=0.2>>> > > Any clues to what I'm doing wrong? Is there a strategy to debug this > kind of thing? The debugger is not like I'm use too. > > Thanks for any help you can offer. Here's a nice page that with a self-explanitory title: "What Every Computer Scientist Should Know About Floating-Point Arithmetic" <http://docs.sun.com/source/806-3568/ncg_goldberg.html> The way money is usually handled is to either use integers for pennies, or use a separate money class which stores money in that way. A nice thing about doing this in Ruby is that once you create your money class, you can add helper methods to Numeric: class Numeric def cents Money.new(self.round) end def dollars Money.new((self*100).round) end end 23.cents #==> $0.23 23.50.dollars #==> $23.50 cheers, Mark