F9bf9d54441b20b8d880313b569cf88d

It almost feels stupid to do this. Is there another way to round up/down to the nearest even number?

class Numeric
  def evenize(round="+")
    eval "self #{round} (self.modulo(2))"
  end
end

177.evenize
#=> 178

177.evenize("-")
#=> 176

Refactorings

No refactoring yet !

F9bf9d54441b20b8d880313b569cf88d

scottburton11

November 18, 2009, November 18, 2009 03:23, permalink

No rating. Login to rate!

Only slightly less evil.

class Numeric
  def evenize(round="+")
    instance_eval "self #{round} (self.modulo(2))"
  end
end
880cbab435f00197613c9cc2065b4f5a

danielharan

November 18, 2009, November 18, 2009 04:38, permalink

No rating. Login to rate!

I'd define floor_even and ceil_even, then round_even if needed. It's more lines of code, but I think it's easier all around.

A8d3f35baafdaea851914b17dae9e1fc

Adam

November 18, 2009, November 18, 2009 06:02, permalink

1 rating. Login to rate!
class Numeric
  def evenize(operator = '+')
    raise ArgumentError, "invalid argument (must be `+' or `-')" unless %w(+ -).include?(operator)
    round.send(operator, modulo(2))
  end
end
F9bf9d54441b20b8d880313b569cf88d

scottburton11

November 18, 2009, November 18, 2009 09:35, permalink

No rating. Login to rate!

I like that.

For what it's worth, here's #oddize

class Numeric
  def oddize(operator = '+')
    raise ArgumentError, "invalid argument (must be `+' or `-')" unless %w(+ -).include?(operator)
    self %2 > 0 ? self : round.send(operator, 1)
  end
end
F4192eeb4b26e96deab8b5c68926105d

Muke Tever

November 23, 2009, November 23, 2009 00:21, permalink

1 rating. Login to rate!

The above don't seem to handle fractions, as I assume you might want, given it's being attached to Numeric and not, say, Integer.

I agree with danielharan about separating evenizing upwards from evenizing downwards, if only because passing "+" or "-" is arbitrary based on the implementation. But you wanted a different way, so:

class Numeric
  def evenize_ceil
    self.quo(2).ceil * 2
  end
  
  def evenize_floor
    self.quo(2).floor * 2
  end
  
  def oddize_ceil
    (self - 1).evenize_ceil + 1
  end
  
  def oddize_floor
    (self - 1).evenize_floor + 1 
  end


  # if you insist
  def evenize(upwards = true)
    upwards ? evenize_ceil : evenize_floor
  end

  def oddize(upwards = true)
    upwards ? oddize_ceil : oddize_floor
  end

  # Bonus methods - round to the nearest even or odd number.
  def evenize_round
    (self + 1).evenize_floor
  end 

  def oddize_round
    (self + 1).oddize_floor
  end
end

Your refactoring





Format Copy from initial code

or Cancel