为什么sqrt()不是Numeric的方法?

时间:2010-05-16 16:34:05

标签: ruby oop

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

E.g。而不是

Math.sqrt(5)

拥有

会更有意义
5.sqrt

同样适用于sincostanlog10等等。

有谁知道为什么所有这些函数都在Math模块中结束了?

5 个答案:

答案 0 :(得分:23)

我不知道Ruby的早期历史,但我感觉Math模块是在C< math.h>之后建模的。头。不过,它在Ruby标准库中是一个奇怪的东西。

但是,这是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

答案 1 :(得分:8)

要扩展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类的风险;迈克尔可能正处于历史遗留问题的正确轨道上。

答案 2 :(得分:7)

我已经重写了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

答案 3 :(得分:3)

在讨论模块和名称空间时,编程Ruby(pickaxe)给出了一个混合了数学函数的对象的例子,并且混合了道德的函数,以便它可以计算how many angels can dance on the head of a pin。然后它指出,如果没有适当的命名空间,sin可能是一个含糊不清的术语。

所以也许是关于命名空间污染。

答案 4 :(得分:2)

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