Почему sqrt() не является методом Numeric?
В Ruby все является объектом. Вот почему я не понимаю, почему у нас есть модуль Math. Мне кажется, что большинство (все?) Функций в модуле Math должны были быть методами для числовых типов, таких как Integer, Float и т.д.
например. вместо
Math.sqrt(5)
было бы разумнее иметь
5.sqrt
То же самое относится к sin
, cos
, tan
, log10
и т.д.
Кто-нибудь знает, почему все эти функции оказались в модуле Math?
Ответы
Ответ 1
Я не знаю раннюю историю Ruby, но я чувствую, что модуль Math был смоделирован после 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
Чтобы расширить на Майкл ответ, нет необходимости определять все эти методы вручную. Обратите внимание, что я явно пропускаю два метода 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
, я действительно не уверен в хорошей причине. Я не думаю, что загрязнение пространства имен как упомянутый Андрей является особенно рискованным в классе Numeric
; Майкл, вероятно, находится на правильном пути с историческим переносом.
Ответ 3
Я переписал ответ 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
Ответ 4
Когда речь идет о модулях и пространствах имен, программирование Ruby (кирка) дало пример объекта, в котором смешались как математические функции, так и функции, связанные с изменением морали, чтобы он мог вычислить сколько ангелов могут танцевать на голове штыря. Затем он отметил, что без надлежащего пространства имен sin
может быть двусмысленным.
Так что, возможно, это касается загрязнения пространства имен.
Ответ 5
5 ** 0.5
демонстрирует, что оператор экспоненциальности ruby может обрабатывать квадратные корни напрямую, так как для log, sin и т.д., это имеет больше смысла для меня как глобальных функций, а не методов: их происхождение находится в математике и не тесно связано ни с одним float.