在Ruby中,一切都是对象。这就是为什么我不明白为什么我们有数学模块。在我看来,Math模块中的大多数(全部?)函数应该是Integer,Float等数值类型的方法。
E.g。而不是
Math.sqrt(5)
拥有
会更有意义5.sqrt
同样适用于sin
,cos
,tan
,log10
等等。
有谁知道为什么所有这些函数都在Math模块中结束了?
答案 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的答案,使其更简洁,并且不需要删除hypot
和ldexp
,因为我自己使用这种方法。
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等,这些对我来说更有意义作为全局函数而不是方法:它们的起源是数学并且与它们没有密切关系任何一个浮动实例。