B S*_*ven 2 ruby constructor overriding overloading ruby-1.9.2
可能重复:
在Ruby中有没有办法重载初始化构造函数?
BigDecimal不会像初始值那样使用浮点数,所以我正在编写一个构造函数来处理它.它似乎忽略了initialize方法并调用默认构造函数.
它抛出 TypeError can't convert Float into String (TypeError)
该方法format确实有效.
文件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
Run Code Online (Sandbox Code Playgroud)
然后,在文件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)
Run Code Online (Sandbox Code Playgroud)
Ruby 1.9.2
代码问题:
你使用猴子补丁而不是继承,所以在你的initialize方法中,super会调用initialize方法Object,这是BigDecimal的超类.要调用默认构造函数,您必须使用其他方法,如下所示.
您没有为该initialize方法添加参数.
BigDecimal将float作为构造函数参数
因此,
您可以直接使用默认构造函数并将float传递为:
BigDecimal.new(34.343, 5) # 5 is the precision
Run Code Online (Sandbox Code Playgroud)您可以通过以下方式覆盖构造函数:
注意:我们通常使用别名initialize方法.但是在这种情况下,这似乎不起作用(由于某些未知原因initialize未被调用)...所以我们必须使用new更为基础的别名方法.
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)>
Run Code Online (Sandbox Code Playgroud)
BigDecimal不会像初始值那样使用浮点数
你确定吗?
BigDecimal.new(2.4)
#=>ArgumentError: can't omit precision for a Rational.
Run Code Online (Sandbox Code Playgroud)
所以你必须给出一个精度作为第二个参数:
BigDecimal.new(2.4, 2)
#=> #<BigDecimal:7ff689b0f2e8,'0.24E1',18(36)>
Run Code Online (Sandbox Code Playgroud)
文档并未指出1.9.2和1.9.3之间的变化.