Working through your gem and it looks pretty sweet. Ran into some entertaining error that I had no idea how to solve so I took a deeper dive.
The error occurs with Ruby 1.9.3p0 and Rails 3.2.3.
When you attempt to something simple like
rate = Rate.new(0.04, :effective, :duration => 360)
amortization = Amortization.new(100000, rate)
You get an error
wrong argument type Flt::DecNum (expected scalar Numeric)
Investigating, this is the stack trace
If I hop over to Rates RB and update the @periods initializer from
@periods = case input
when :annually then Flt::DecNum 1
when :continuously then Flt::DecNum.infinity
when :daily then Flt::DecNum 365
when :monthly then Flt::DecNum 12
when :quarterly then Flt::DecNum 4
when :semiannually then Flt::DecNum 2
when Numeric then Flt::DecNum input.to_s
else raise ArgumentError
and update the "monthly" setting to
when :monthly then '12.0'.to_d
It seems to work.
Of the top of your head, do you know what I lose if I update all those Flt:DecNum initializers to something simpler?
Thanks & thanks for the great work on the gem.
To answer your question: no, I believe the result is equivalent using .to_d. I think I wrote this case statement before I got tired of initializing DecNum everywhere.
That said, I have a couple of follow-up questions:
when Flt::DecNum then input
Thanks again for your feedback. It's always great to hear from people using the library.
Ok thanks. I'm the newbiest of all rails newbies, so I have no idea what's happening. I ran the ruby tests outside of rails and it worked. What it looked like to me was an exception thrown when you try to call ".to_d" on an Flt::DecNum. I wonder if there's something in rails that overrides the standard to_d in a way that cases this.
hello, i am getting this exact same error using Rails 3.2.6 / Ruby 1.9.3p194. thanks so much for posting about this. is there anyway to resolve so that i may use the Finance gem?
and to the author (Bill), how could adding the "when Flt::DecNum then input" resolve?
actually i tried adding the line "when Flt::DecNum then input" and this didn't resolve, but doing the '12.0'.to_d suggested by ReidCarlberg seemed to work. i'll do more testing. please do let me know any suggestions on how to properly use this with Rails. Thanks!
Digging a little further, I think the core issue is that the core BigDecimal's to_d is beating out Finance's to_d on Numeric.
ruby-1.9.3-p194 :003 > 1.method(:to_d).source_location
NameError: undefined method `to_d' for class `Fixnum'
from (irb):3:in `method'
from ~/.rvm/rubies/ruby-1.9.3-p194/bin/irb:16:in `<main>'
ruby-1.9.3-p194 :004 > require 'bigdecimal/util'
ruby-1.9.3-p194 :005 > 1.method(:to_d).source_location
=> ["~/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/bigdecimal/util.rb", 13]
bigdecimal/util is included by ActiveRecord:
I tried adding this in an initializer:
if self.instance_of? DecNum
But it only works for Fixnums, not for Floats too:
ruby-1.9.3-p194 :003 > 1.2.method(:to_d).source_location
=> ["~/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/1.9.1/bigdecimal/util.rb", 30]
ruby-1.9.3-p194 :004 > 1.method(:to_d).source_location
=> ["~/.../<my_rails_project>/config/initializers/fixnum_to_d_method_for_finance.rb", 2]
My intent in defining the #to_d method was to integrate nicely with existing Ruby methods and define as few new methods on existing classes as possible. At least in this case, this now appears to be more trouble than it is worth.
I see two potential ways out:
1. Rename #to_d to something like #to_decimal. My guess is that there aren't many external functions that rely on the #to_d method as implemented in Finance, so this shouldn't break too much existing code.
2. We could drop the flt library and adopt BigDecimals internally. There are some drawbacks to this, documented at the bottom of the flt page, but nothing catastrophic. This could also make it easier to use Ruby's Newton's Method solver, which currently only accepts BigDecimals, and we have to convert back and forth.
I'm open to other suggestions as well if anyone has an opinion one way or the other.
[#9] Wrap all #to_d calls with Flt::DecNum.new so we don't have type …
[#9] Documentation updates that work within a Rails environment
Does this work with rails yet? It would be awesome if I could help out in some way.
[Fixes #9]: Explicitly initializes the places where Flt::DecNum is ex…
…pected rather than relying on to_d