2014-02-17 2 views
5

У меня есть приложение на Ruby On Rails.Рубиновое деление бесконечности/NaN должно вернуться 0

В приложении Я хочу переопределить родительский класс деления в Ruby.

Для справки нижеприведенные исключения.

I Googled везде. Я хочу переопределить метод разделения ruby ​​в приложении.

Для того, чтобы для результатов ниже он должен был возвращать ноль.

0.0/0 
=> NaN 

1.0/0 
=> Infinity 
ZeroDivisionError: divided by 0 

Я могу справиться с этим, изменяя код везде, когда делят операцию. Но я хочу сэкономить свое время, переопределив сам метод.

+6

Надеюсь, я никогда не буду работать над кодовой базой, где рубиновое ядро ​​- обезьяна, заплатящая за лень – apneadiving

+0

Как это 'a = 0 if (0.0/0) .nan? ; b = 0, если (1.0/0) .конечный? ; a # => 0 b # => 0'? –

+0

@Arup, спасибо, но я хочу переопределить родительский метод разделения в ruby ​​... Я выполняю эту операцию почти в 200 местах в своем приложении. Поэтому лучше написать собственный метод разделения в приложении. –

ответ

3

Очень похоже на: How can I redefine Fixnum's + (plus) method in Ruby and keep original + functionality?

class Float 
    alias_method :old_div, :/ 

    def /(y) 
    return NAN if self == y && y == 0.0 
    return INFINITY if self == 1.0 && y == 0.0 
    self.old_div(y) 
    end 
end 

Я знаю, что код выше не может быть то, что вы именно хотите. Не стесняйтесь настраивать его так, как вы хотите =)

+0

Спасибо .. Это хороший способ ... работа для меня .. –

+0

Я просто заменяю NAN и INFINITY на 0.0 –

+3

Это заставляет меня хотеть плакать. Каждый раз, когда этот код называется, Бог убивает щенка. – zetetic

2

Переопределение деления Fixnum, Decimal и т. Д. Возможно, но может и не быть лучшим решением для вас. Вам нужно будет переопределить методы в нескольких классах, и они могут иметь некоторые очень неприятные побочные эффекты (помните - эти методы не вызывают только из вашего кода!)

Я бы предложил вам написать вспомогательный модуль, который будет реализовать это новое поведение, и что вы могли бы назвать его вместо /:

module WeirdMath 
    self.div(n1, n2) 
    result = n1/n2 
    result.nan? || result.infinite? ? 0 : result 
    rescue 
    0 
    end 
end 

WeirdMath.div(0.0, 0) # => 0 
WeirdMath.div(1.0, 0) # => 0 
WeirdMath.div(3.0, 2) # => 1.5 
+0

Это как переписать код во всех местах .., что я не буду предпочесть. Не могли бы вы предложить, как мне переопределить метод деления? –

+0

Я прошу различить - вы держите логику в одном месте. Вы можете делать то, что предлагает @Abdo, но тогда вы должны сделать это для 'Decimal',' Fixnum' и других для вас, чтобы получить тот же конечный результат, - и тогда вы можете очень хорошо сломать что-то еще - и это будет сука, чтобы отслеживать ... –

5

Вам не нужен специальный метод или расширение класса float, как указано в других ответах.

Ruby предоставляет вам метод класса Float для этого называемого .finite?

http://ruby-doc.org/core-1.9.3/Float.html#method-i-finite-3F

конечной? → true или false Возвращает true, если flt - допустимое число с плавающей запятой IEEE (оно не бесконечно, а nan? False).

if value.finite? == false 
value = 0 
else 
value = value 
end 

Приведенный выше пример является немного многословным.

+0

.finite? на самом деле возвращает true или false, поэтому false здесь не нужно. –

+0

Но это помогло мне, я предлагаю это как правильное вместо этого странного использования 'self' вверху! –

Смежные вопросы