Skip to content

Instantly share code, notes, and snippets.

@wkjagt
Last active August 29, 2015 14:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wkjagt/5c873c55de08ba95c356 to your computer and use it in GitHub Desktop.
Save wkjagt/5c873c55de08ba95c356 to your computer and use it in GitHub Desktop.
A readable way to express percentage calculations

Adds a readable way of expressing percentage calculations.

TL;DR

200 - 15.percent # 170

PercentageSupport

module PercentageSupport
  Percentage = Struct.new(:value) do
    def -@
      Percentage.new(-self.value)
    end
    
    def +(operand)
      Percentage.new(self.value + operand.value)
    end

    def -(operand)
      Percentage.new(self.value - operand.value)
    end
    
    def *(operand)
      Percentage.new(self.value * operand)
    end

    def /(operand)
      Percentage.new(self.value / operand)
    end
    
    def self.transform_operand(numeric, operand)
      return operand unless operand.is_a? Percentage
      numeric.to_d * (operand.value) / 100
    end
  end

  def percent
    Percentage.new(self.to_d)
  end
  
  def -(operand)
    super(Percentage.transform_operand(self, operand))
  end
  
  def +(operand)
    super(Percentage.transform_operand(self, operand))
  end
  
  def *(operand)
    return operand * self if operand.is_a? Percentage
  end
end

Usage

Monkey patch Fixnum and Float:

Fixnum.prepend PercentageSupport
Float.prepend PercentageSupport

And then use it like this:

325 - 10.percent # 292.5

or:

adjustment = -10.percent
1900 + adjustment # 1710

or

adjustment_a = -10.percent
adjustment_b = -5.percent

total_adjustment = adjustment_a + adjustment_b

100 + total_adjustment # 85

or:

result = 100 - 2 * 10.percent # 80

or:

100 - 10.percent / 2 # 95
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment