Possible Duplicate:
In Ruby is there a way to overload the initialize constructor?
BigDecimal does not take a float as in initial value, so I am writing a constructor to handle it. It seems to be ignoring the initialize method and calling the default constructor.
It throws TypeError can't convert Float into String (TypeError)
The method format does work.
file BigDecimal.rb:
require 'bigdecimal'
class BigDecimal
def initialize
if self.class == Float
super self.to_s
end
end
def format
sprintf("%.2f", self)
end
end
Then, in file test.rb:
require 'BigDecimal' # => true
bd = BigDecimal.new('54.4477') # works
puts bd.format # 54.44
bd2 = BigDecimal.new(34.343) # TypeError: can't convert Float into String (TypeError)
Ruby 1.9.2
Problems with your code:
You use a monkey patch instead of inheriting, so in your initialize method, super will call the initialize method of Object, which is the super class of BigDecimal. To call the default constructor, you have to use some other method as showing below.
You did not put arguments for the initialize method.
BigDecimal DOES take float as constructor argument
Therefore,
You can use directly the default constructor and pass a float as:
BigDecimal.new(34.343, 5) # 5 is the precision
You can override the constructor in this way:
NOTE: we usually alias initialize method. However in this case this does not seem to work (for some unknown reason that initialize does not get called)... So we have to alias new method which is more fundamental.
require 'bigdecimal'
class BigDecimal
class << self
alias_method :__new__, :new #alias the original constructor so we can call later
def new(*args)
if args.length == 1 && args[0].is_a?(Float)
__new__(args[0].to_s)
else
__new__(*args)
end
end
end
def format
sprintf("%.2f", self)
end
end
BigDecimal.new(12.334)
#<BigDecimal:10a9a48,'0.12334E2',18(18)>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With