代码之家  ›  专栏  ›  技术社区  ›  KaptajnKold

为什么sqrt()不是数值方法?

  •  26
  • KaptajnKold  · 技术社区  · 15 年前

    在Ruby中,一切都是一个对象。这就是为什么我不明白为什么我们有数学模块。在我看来,这是最重要的(全部?)数学模块中的函数应该是整数、浮点等数值类型的方法。

    例如,而不是

    Math.sqrt(5)
    

    这样做更有意义

    5.sqrt
    

    同样的道理 sin , cos , tan , log10 等等。

    有人知道为什么所有这些函数都会出现在数学模块中吗?

    5 回复  |  直到 7 年前
        1
  •  23
  •   Michael Melanson    15 年前

    我不知道Ruby的早期历史,但我觉得数学模块是根据c<math.h>标题建模的。不过,在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
  •  8
  •   Community CDub    8 年前

    展开 Michael's answer 不需要手工定义所有这些方法。注意,我显式地跳过了采用两个参数的两个数学方法。

    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 尤其是在 数字的 课堂上,迈克尔可能在历史遗留物的正确轨道上。

        3
  •  7
  •   Stephen Touset    14 年前

    我把马克的答案改写得更简洁,不需要删掉。 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
    
        4
  •  3
  •   Andrew Grimm atk    15 年前

    在谈到模块和名称空间时,Ruby(pickaxe)编程给出了一个例子,其中一个对象既包含数学函数,也包含与道德有关的函数,因此它可以计算 how many angels can dance on the head of a pin . 然后指出,如果没有适当的名称间距, sin 可能是一个模棱两可的术语。

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

        5
  •  2
  •   user8585295    7 年前

    5 ** 0.5 演示Ruby的求幂运算符可以直接处理平方根,例如log、s in等,这些对我来说更像是全局函数,而不是方法:它们的起源是数学的,与任何一个float实例都不密切相关。