如何打开String类来重写to_s方法

时间:2014-04-27 08:03:05

标签: ruby

我想重写to_s方法,以便以number_to_currency格式打印这些钱。我该怎么做?有没有办法以Integer格式打印所有Floatnumber_to_currency变量而不调用number_to_currency方法?

我在控制台中运行了这段代码:

require 'pry'
require 'action_view'
include ActionView::Helpers


class String
  def to_s(x)
    number_to_currency(x)
  end
end

sum = 0
0.upto(one_fifth-1) do |line_no|
  sum += lo_to_hi[line_no].last
end
ap("bottom #{one_fifth} sum:#{sum}, average #{sum/one_fifth}")

并获得此例外:in `to_s': wrong number of arguments (0 for 1) (ArgumentError)

3 个答案:

答案 0 :(得分:1)

我认为to_s不应该有一个参数(因为父类中的定义(可能是Object)没有。)。您既可以使用to_s(无参数),也可以创建一个接受参数但不称为to_s的新方法

换句话说,如果要覆盖方法,则必须保持完全相同的方法签名(即,其名称和所需的参数数量)。

如果你尝试怎么办?

class String
    def to_s_currency(x)
        number_to_currency(x)
    end
end

答案 1 :(得分:1)

首先,to_s方法没有参数。当您不知道该方法是否也调用to_s时,调用to_s中的其他方法也很危险。 (似乎number_to_currency确实调用了数字to_s。经过多次尝试,这个技巧可能适用于你的float和fixnum数字:

class Float
  include ActionView::Helpers::NumberHelper
  alias :old_to_s :to_s
  def to_s
    return old_to_s if caller[0].match(':number_to_rounded')
    number_to_currency(self.old_to_s)
  end
end

class Fixnum
  include ActionView::Helpers::NumberHelper
  alias :old_to_s :to_s
  def to_s
    return old_to_s if caller[0].match(':number_to_rounded')
    number_to_currency(self.old_to_s)
  end
end

请注意,在此技巧中,该方法使用match(':number_to_rounded')来检测调用方并避免递归调用。如果您的任何一种方法的名称类似于“number_to_rounded”并且在您的号码上拨打to_s,那么它也会获得原始号码。

答案 2 :(得分:0)

正如您要在int中打印所有floatnumber_to_currency变量一样,您必须覆盖to_s / {{1}中的Fixnum函数}和Integer类,如下所示:

正如Stefan所指出的,FloatInteger有一个共同的父类:Float,您可以这样做:

Numeric