【问题标题】:Override BigDecimal to_s default in Ruby在 Ruby 中覆盖 BigDecimal to_s 默认值
【发布时间】:2010-02-25 15:12:06
【问题描述】:

当我从数据库表中检索数据时,会填充一个数组。一些字段被定义为小数和货币字段,并且在数组中它们表示为 BigDecimal。

我使用这些数组值来填充 CSV 文件,但问题是所有 BigDecimal 值默认以科学格式表示(这是 BigDecimal to_s 方法的默认行为)。我可以使用 to_s('F') 来显示值,但是如何覆盖默认值?

【问题讨论】:

    标签: ruby arrays default bigdecimal


    【解决方案1】:

    这是建立在@Farrel 的答案之上的,但不会用无用的old_xyz 方法污染方法命名空间。另外,为什么不直接使用默认参数呢?

    class BigDecimal
      old_to_s = instance_method :to_s
    
      define_method :to_s do |param='F'|
        old_to_s.bind(self).(param)
      end
    end
    

    在 Ruby 1.8 中,这有点难看:

    class BigDecimal
      old_to_s = instance_method :to_s
    
      define_method :to_s do |param|
        old_to_s.bind(self).call(param || 'F')
      end
    end
    

    或者,如果您不喜欢上述代码收到的警告:

    class BigDecimal
      old_to_s = instance_method :to_s
    
      define_method :to_s do |*param|
        old_to_s.bind(self).call(param.first || 'F')
      end
    end
    

    【讨论】:

    • 试过这段代码,但得到“语法错误,意外'=',需要tCOLON2或'['或'。'在define_method 行
    • @Skoppensboer:具有块默认参数的可选参数是 Ruby 1.9 的功能。 block.(foo) 语法也是如此。在 Ruby 1.8 中,您必须使用不同的解决方案来提供默认参数,并且您需要使用 call 方法。
    • Thx Joerg,我认为可能是这样,但我想帮助的人仍在 1.8.7 上
    • 嗨,知道为什么我在使用此代码时会得到SystemStackError (stack level too deep) 吗?不仅是您的 3 个示例,任何重新定义 to_s 的尝试都会因该错误而失败。
    【解决方案2】:
    class BigDecimal
      alias old_to_s to_s
    
      def to_s( param = nil )
          self.old_to_s( param || 'F' )
       end
    end
    

    【讨论】:

    • 太棒了!谢谢法雷尔和大卫,我知道这应该是可能的,只是不知道该怎么做。
    • 请不要这样做。它使用完全无用的old_to_s 方法不必要地污染了BigDecimal 的命名空间。
    【解决方案3】:

    Ruby 让这一切变得简单。看:

    class BigDecimal
      def to_s
        return "Whatever weird format you want"
      end
    end
    
    # Now BigDecimal#to_s will do something new, for all BigDecimal objects everywhere.
    

    这种技术称为猴子补丁。正如您可能从名称中猜到的那样,您应该谨慎使用它。不过,这种用法对我来说似乎是合理的。

    【讨论】:

      猜你喜欢
      • 2011-12-20
      • 1970-01-01
      • 2017-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-07
      • 2022-01-25
      相关资源
      最近更新 更多