Pourquoi sqrt() n'est-il pas une méthode sur Numeric?

Dans Ruby tout est un objet. C'est pourquoi je ne comprends pas pourquoi nous avons le module de mathématiques. Il me semble que la plupart (tous?) des fonctions dans le module Math auraient dû être des méthodes sur les types numériques comme Integer, Float et ainsi de suite.

Par exemple au lieu de

Math.sqrt(5)

, Il serait plus logique d'avoir

5.sqrt

Est La même chose pour sin, cos, tan, log10 et ainsi de suite.

Est-ce que quelqu'un sait pourquoi toutes ces fonctions se sont retrouvées dans le module de mathématiques?

24
demandé sur KaptajnKold 2010-05-16 20:34:04

5 réponses

Je ne connais pas les débuts de Ruby, mais j'ai l'impression que le module de mathématiques a été calqué sur le C en-tête. C'est un canard étrange dans la bibliothèque Ruby standard.

Mais, C'est Ruby! Donc, vous pouvez toujours buste sur le patching de singe!

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
22
répondu Michael Melanson 2010-05-16 16:44:36

Pour développer la réponse de Michael , il n'est pas nécessaire de définir toutes ces méthodes à la main. Notez que je saute explicitement les deux méthodes mathématiques qui prennent deux arguments.

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

Sortie:

5.0
2.0 

En ce qui concerne exactement pourquoi ces méthodes ne sont pas déjà incluses dans Numeric, Je ne suis vraiment pas sûr d'une bonne raison. Je ne pense pas que la pollution de l'espace de noms comme Andrew mentionné est particulièrement un risque dans la classe Numeric; Michael est probablement sur la bonne voie avec historic de report.

7
répondu Mark Rushakoff 2017-05-23 12:09:57

J'ai réécrit la réponse de Mark pour être plus concise, et ne pas nécessiter de supprimer hypot et ldexp, puisque j'utilise moi-même cette approche.

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
6
répondu Stephen Touset 2011-04-08 19:02:05

En parlant de modules et d'espaces de noms, la programmation de Ruby (la pioche) a donné un exemple d'objet avec à la fois des fonctions mathématiques mélangées et des fonctions liées à la moralité mélangées, de sorte qu'il puisse calculer combien d'anges peuvent danser sur la tête d'une épingle . Il a ensuite noté que sans espace de noms approprié, sin pourrait être un terme ambigu.

Alors peut-être que c'est à propos de la pollution de l'espace de noms.

3
répondu Andrew Grimm 2010-05-16 22:58:29

5 ** 0.5 démontre que l'opérateur d'exponentiation de ruby peut gérer directement les racines carrées, comme pour log, sin etc, celles-ci ont plus de sens pour moi en tant que fonctions globales plutôt que de méthodes: leurs origines sont en mathématiques et ne sont pas étroitement liées à une instance float.

2
répondu 2017-09-09 19:42:38