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?
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
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.
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
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.
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.