Any tricks re using " eql(5.5)", but where 5.5 is a decimal not float?


Sent from my mobile device

(woops - full email below)

Hi,

My rails migrations / mysql database uses Decimal and I’ve noticed in
my rspec when I do a “…should eql(5.5)” that they’re failing as the
expected result here is a float not a decimal. For example see
extract below:

 expected 6.5, got #<BigDecimal:23d8284,'0.65E1',8(8)> (using .eql?)

What’s the best way of addressing this? Is there trick regarding the
easiest way to address this?

Thanks

On Sat, Nov 8, 2008 at 9:18 AM, Greg H.

On Fri, Nov 7, 2008 at 3:24 PM, Greg H. <
[email protected]> wrote:

expected 6.5, got #<BigDecimal:23d8284,'0.65E1',8(8)> (using .eql?)

How about just expecting BigDecimal(‘5.5’)?

///ark

There’s my C roots showing. :slight_smile: That should be BigDecimal.new(‘5.5’), of
course.

“Greg H.” [email protected] writes:

Do you mean BigDecimal? Anyway, you should probably be using == instead
of eql.

5.5 == BigDecimal.new(‘5.5’)
=> true
5.5.eql? BigDecimal.new(‘5.5’)
=> false

eql? is object identity and is generally not what you’re after.

Pat

On Fri, Nov 7, 2008 at 3:51 PM, Pat M. [email protected] wrote:

eql? is object identity and is generally not what you’re after.

Yeah, but

BigDecimal(‘5.5’).eql? BigDecimal(‘5.5’)
=> true

So it’s either creating value objects (like Symbol) or BigDecimal.eql?
doesn’t do object equality.

What’s interesting is that you can create BigDecimals this way (without
calling new). You can do it with Strings, too.

String(‘asdf’)
=> “asdf”

But not everything:

Hash(:a => 5)
NoMethodError: undefined method `Hash’ for #Object:0x3799c
from (irb):12

As Johnny Carson used to say, “I did not know that.”

///ark

On Fri, Nov 7, 2008 at 6:24 PM, Greg H.
[email protected] wrote:

What’s the best way of addressing this? Is there trick regarding the
easiest way to address this?

You aren’t by chance using decimals to represent money are you?


Zach D.
http://www.continuousthinking.com

yep - this was recommended on forums over float - why?

On Fri, Nov 7, 2008 at 9:12 PM, Greg H.
[email protected] wrote:

yep - this was recommended on forums over float - why?

You are in for a lot of headaches in you application resorting to
decimal fields in the database, since it restores them as BigDecimals.
It sucks to deal with BigDecimals in your app. I very highly recommend
the Money library. I recommend installing it as a plugin and using the
CollectiveIdea fork.

Even if all you do is take 20 minutes to check out the Money library
in a dummy app, I think you will be glad you did.

Zach

expected result here is a float not a decimal. For example see
Zach D.
http://www.continuousthinking.com
http://www.mutuallyhuman.com


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


Zach D.
http://www.continuousthinking.com

in fact I guess I was fishing for an easier way than this…if one
exists? or is ruby & rspec “eql()” just strict here in terms of
types?

“Greg H.” [email protected] writes:

How about just expecting BigDecimal(‘5.5’)?

///ark

I’m not sure if you got my email before, but 6.5 ==
BigDecimal.new(‘6.5’). So use == instead and you should be good.

Pat

thanks Pat - yes I missed it when reading your email - I’d been using
“.eql” for everything…thanks

very bizzare but whilst I needed to use this approach to fix one of my
tests, I realised the test before was working without having to make
it a big decimal - go figure :slight_smile:


it “should return last IR when date > last interest rate” do
@source_bank.ir(Time.now.to_date + 1.years).should == 8.5 # <==
WORKED FINE
end

it “should return latest IR not greater than date specified when a
date is passed” do
@source_bank.ir(Time.now.to_date + 8.days).should ==
BigDecimal.new(‘6.5’) # <== NEEDED TO USE BigDecimal here
end

On Sat, Nov 8, 2008 at 3:37 PM, Greg H.

On Nov 08, 2008, at 2:18 am, Zach D. wrote:

[email protected] wrote:

yep - this was recommended on forums over float - why?

You are in for a lot of headaches in you application resorting to
decimal fields in the database, since it restores them as BigDecimals.
It sucks to deal with BigDecimals in your app. I very highly recommend
the Money library. I recommend installing it as a plugin and using the
CollectiveIdea fork.

Ha, I wrote the ActiveRecord patch so this was possible :slight_smile:

The reason for storing monetary values as SQL decimals is that they
aren’t subject to rounding errors[1]. I used to work in the finance
sector, and it was absolutely unacceptable to expose financial
calculations to these errors. Hence I added support in ActiveRecord
so we could use Rails; it was just not an option otherwise.

The decision you have to make is between the extra effort now of using
decimals in your code vs the extra effort later of explaining to your
users why your calculations sometimes come out wrong. And that
depends on how much your users value knowing that these figures are
correct.

Ashley

[1]


http://www.patchspace.co.uk/

On Nov 10, 2008, at 12:21 am, Greg H. wrote:

Ashley - what’s you’re recommendation re using BigDecimal (which does
work as you point out) and the Money gem (which it sounds like makes a
dev’s life a bit easier)??? Is it worth trying to port an application
from use of BigDecimal to Money gem???

Hi Greg

I’d use the money gem if and only if it’s underlying implementation is
BigDecimal or some other fixed-precision system. I’ve had a look over
it and it appears to use integers to store values as small as 1/100 of
the base unit. So as long as you don’t need to use anything smaller
than that in calculations (ie, you only add, and never multiply,
values - eg for tax calculations) it will be fine.

I’ll try not to say too much more, we’re straying well away from RSpec
territory…

Ashley


http://www.patchspace.co.uk/

Ashley - what’s you’re recommendation re using BigDecimal (which does
work as you point out) and the Money gem (which it sounds like makes a
dev’s life a bit easier)??? Is it worth trying to port an application
from use of BigDecimal to Money gem???

On Sun, Nov 9, 2008 at 10:27 PM, Ashley M.