【问题标题】:Why is sqrt() not a method on Numeric?为什么 sqrt() 不是 Numeric 的方法?
【发布时间】:2011-02-20 03:11:30
【问题描述】:

在 Ruby 中,一切都是对象。这就是为什么我不明白为什么我们有数学模块。在我看来,Math 模块中的大多数(全部?)函数应该是数字类型的方法,如 Integer、Float 等。

例如而不是

Math.sqrt(5)

拥有它会更有意义

5.sqrt

sincostanlog10 等也是如此。

有谁知道为什么所有这些函数最终都出现在数学模块中?

【问题讨论】:

  • 5.sqrt 太落后了
  • Kaptajn,因为这太 OOP IMO,对于从其他语言迁移的程序员来说太奇怪了
  • #abs 是一种方法:-6.abs #=> 6

标签: ruby oop


【解决方案1】:

我不知道 Ruby 的早期历史,但我感觉 Math 模块是根据 C 标头建模的。不过,它在 Ruby 标准库中是一只奇怪的鸭子。

但是,它是鲁比!所以你总是可以打掉猴子补丁!

class Float
  def sqrt; Math.sqrt(self); end
  def sin; Math.sin(self); end
  def cos; Math.cos(self); end
  def tan; Math.tan(self); end
  def log10; Math.log10(self); end
end

【讨论】:

    【解决方案2】:

    要扩展Michael's answer,无需手动定义所有这些方法。请注意,我明确跳过了采用两个参数的两个 Math 方法。

    class Numeric
      (Math.methods - Module.methods - ["hypot", "ldexp"]).each do |method|
        define_method method do
          Math.send method, self
        end
      end
    end
    
    puts 25.sqrt
    puts 100.log10
    

    输出:

    5.0
    2.0 
    

    关于这些方法为什么不包含在Numeric 中的确切原因,我真的不确定一个很好的理由。我不认为Andrew mentioned 的命名空间污染在Numeric 类中特别危险;迈克尔可能走上了历史遗留问题的正确轨道。

    【讨论】:

    • 改成define_method(method) do |*args| Math.send(method, self, *args) end,就不需要排除hypot或者ldexp了。
    • 表达式 (Math.methods - Module.methods) 也可以简写为 Math.methods(false)
    • 为方便起见合并成一行(在数字类中):Math.methods(false).each {|m| define_method m do |*args| Math.send m, self, *args end }
    【解决方案3】:

    我已将 Mark 的答案重写为更简洁,并且不需要删除 hypotldexp,因为我自己正在使用这种方法。

    class Numeric
      Math.methods(false).each do |method|
        define_method method do |*args|
          Math.send(method, self, *args)
        end
      end
    end
    
    >> 3.hypot(4)
    => 5.0
    
    >> Math::PI.sqrt
    => 1.7724538509055159
    
    >> 10.log10
    => 1
    

    【讨论】:

      【解决方案4】:

      在谈到模块和命名空间时,Ruby 编程(镐)给出了一个对象的示例,其中混合了数学函数和与道德有关的函数,以便它可以计算 how many angels can dance on the head of a pin。然后它指出,如果没有正确的命名空间,sin 可能是一个模棱两可的术语。

      所以可能是关于命名空间污染。

      【讨论】:

      • 这个问题通常适用于鸭子类型,而不仅仅是数学函数。我怀疑这可能是原因。
      【解决方案5】:

      5 ** 0.5 证明 ruby​​ 的幂运算符可以直接处理平方根,例如 log、sin 等,这些对我来说更有意义的是全局函数而不是方法:它们起源于数学,与任何一个都没有密切关系浮动实例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-04
        • 1970-01-01
        • 1970-01-01
        • 2015-08-24
        • 2010-09-09
        • 1970-01-01
        • 2022-12-04
        相关资源
        最近更新 更多