8

I am having an application on Ruby On Rails.

In application I want to override parent class of division in Ruby.

For handling below exceptions.

I Googled everywhere. I want to override ruby division method in application.

So that for below results it should return zero.

0.0 / 0
 => NaN 

1.0 / 0
 => Infinity 
ZeroDivisionError: divided by 0

I can handle it by changing code everywhere while divide operation. But I want to save my time by overriding the method itself.

Dave Newton
  • 158,873
  • 26
  • 254
  • 302
Sumit Munot
  • 3,748
  • 1
  • 32
  • 51
  • 7
    Hopefully I would never work on a codebase where ruby core is monkey patched for laziness' sake – apneadiving Feb 17 '14 at 21:01
  • How is this `a = 0 if (0.0 / 0).nan? ; b = 0 if (1.0 / 0).infinite? ; a # => 0 b # => 0` ? – Arup Rakshit Feb 17 '14 at 21:02
  • @Arup, thanks but I want to override parent method of division in ruby...I am doing this operation on almost 200 places in my application. So it's better to write our own division method in application. – Sumit Munot Feb 17 '14 at 21:11
  • What's the specific issue? It's a method. – Dave Newton Feb 17 '14 at 21:23
  • @DaveNewton, application is crashing due to Nan and Infinity return..I always want output or zero. I am using this division operation multiple times in my application. So I just want to override division method to change return type to zero.. – Sumit Munot Feb 17 '14 at 21:26
  • Right. What's the issue with doing so? And why wasn't the problem identified before doing it in 200 places? – Dave Newton Feb 17 '14 at 21:28
  • That time my database columns was not zero or null..But now requirements changed..So it is needed to change the code.. So I want to do it in simple way... – Sumit Munot Feb 17 '14 at 21:31
  • I feel it would be smatter/safer to write a script that parses the whole code base and replace every places where you have cases of the above issue with a `begin rescue` or some conditional clause as you may find convenient – bjhaid Feb 17 '14 at 22:07

3 Answers3

6

You do not need a special method or to extend the float class as other answers state.

Ruby provides you a method on the Float class for this called .finite?

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

finite? → true or false Returns true if flt is a valid IEEE floating point number (it is not infinite, and nan? is false).

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

The above example is a bit verbose.

jBeas
  • 926
  • 7
  • 20
4

Very similar to: 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

I know the code above might not be what you exactly want. Feel free to customize it the way you want =)

Community
  • 1
  • 1
Abdo
  • 13,549
  • 10
  • 79
  • 98
  • I just replaces NAN and INFINITY with 0.0 – Sumit Munot Feb 17 '14 at 21:46
  • 3
    This makes me want to cry. Every time this code is called, God kills a puppy. – zetetic Feb 17 '14 at 21:46
  • @zetetic haha .. Yup but if you think about it, in web apps for instance, how frequently do you use division? (haha, maybe if we override the division operator and add a counter we can know) – Abdo Feb 17 '14 at 21:48
  • 3
    @Abdo the bigger issue is: how does this affect the difficulty of working on the code base? What happens when a future programmer writes code that relies on the original behavior? It would be better to explicitly rescue errors and leave the `Float` class alone. You may think you're saving time, but you will pay for it in the long run. – zetetic Feb 17 '14 at 21:55
  • 1
    @zetetic I agree, it is very dangerous and I only provided the code for educational purposes (I do not condone it). It's @SumitMunot's choice. On the other hand, I personally like to use method_missing on `Hash` to look up `h[:foo]` by doing `h.foo` and people can feel free to disagree =) – Abdo Feb 17 '14 at 22:01
  • It depends on application to application..As per in my application customization of divide method is the better way to handle these conditions.. Also I agree it's not best practice to override and change the original behavior of methods..But if you need it globally for your app..it's better to prefer this.. – Sumit Munot Feb 17 '14 at 22:35
  • @SumitMunot I could not disagree more. This is double-facepalm territory. – zetetic Feb 18 '14 at 02:12
  • I'd make a decorator class instead and replace values in these expressions with instantiations. I mean... yeah, I used to override `String#length`, which is more insane... – D-side Nov 22 '14 at 19:49
2

Overriding the division of Fixnum, Decimal, etc. is possible, but might not be the best solution for you. You would need to override methods in several classes, and they might have some very nasty side-effects (remember - these methods are not called only from your code!!)

I would suggest you write some helper module, which will implement this new behavior, and that you would call it instead of /:

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
Uri Agassi
  • 36,848
  • 14
  • 76
  • 93
  • It's like rewrite the code on all the places..that I will not prefer..can you please suggest how do I override the division method? – Sumit Munot Feb 17 '14 at 21:37
  • I beg to differ - you keep the logic in one place. You can do what @Abdo suggests, but then you have to do it for `Decimal`, `Fixnum`, and others for you to get to the same end result - and then you might very well break something else - and it will be a bitch to track... – Uri Agassi Feb 17 '14 at 21:39