Class: IncomeTax::Rate

Inherits:
Numeric
  • Object
show all
Extended by:
Forwardable
Includes:
Comparable
Defined in:
lib/income_tax/rate.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(value, other = nil) ⇒ Rate

Returns a new instance of Rate.



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/income_tax/rate.rb', line 35

def initialize(value, other = nil)
  value     = "100%" if value.respond_to? :infinite? and value.infinite?
  value     = Rate.rational(value, other) if other
  _, value  = case value
              when /^\-?\d+(\.\d+)?\%$/ then @preferred_coercion, @to_r = :to_r, value.to_r / 100
              when /^[10\-?]\.\d+$/     then @preferred_coercion, @to_r = :to_r, value.to_r
              when BigDecimal           then @preferred_coercion, @to_d = :to_d, value
              when Rational             then @preferred_coercion, @to_r = :to_r, value
              when Float                then @preferred_coercion, @to_f = :to_f, value
              when Integer              then @preferred_coercion, @to_r = :to_r, value.to_r / 100
              else raise ArgumentError, "cannot handle %p as rate input" % [value]
              end

  @to_d ||= Rate.decimal(value)
  @to_r ||= Float === value ? value.to_s.to_r : value.to_r
  @to_f ||= value.to_f
  @to_i ||= value.to_i
  @to_s ||= (@to_d * 100).to_s("F") + "%"
  @to_s.sub! ".0%", "%"

  @preferred_coercion = :to_i if @to_i == value
end

Instance Attribute Details

#to_dObject (readonly)

Returns the value of attribute to_d.



27
28
29
# File 'lib/income_tax/rate.rb', line 27

def to_d
  @to_d
end

#to_fObject (readonly)

Returns the value of attribute to_f.



27
28
29
# File 'lib/income_tax/rate.rb', line 27

def to_f
  @to_f
end

#to_iObject (readonly)

Returns the value of attribute to_i.



27
28
29
# File 'lib/income_tax/rate.rb', line 27

def to_i
  @to_i
end

#to_rObject (readonly)

Returns the value of attribute to_r.



27
28
29
# File 'lib/income_tax/rate.rb', line 27

def to_r
  @to_r
end

#to_sObject (readonly)

Returns the value of attribute to_s.



27
28
29
# File 'lib/income_tax/rate.rb', line 27

def to_s
  @to_s
end

Class Method Details

.decimal(input) ⇒ Object



17
18
19
20
# File 'lib/income_tax/rate.rb', line 17

def self.decimal(input)
  return input.to_d unless input.is_a? Rational
  input.to_d(input.to_f.to_s.size)
end

.new(input, other = nil) ⇒ Object



12
13
14
15
# File 'lib/income_tax/rate.rb', line 12

def self.new(input, other = nil)
  return super unless other.nil?
  input.is_a?(Rate) ? input : super
end

.rational(input, other) ⇒ Object



22
23
24
25
# File 'lib/income_tax/rate.rb', line 22

def self.rational(input, other)
  return 0r if input == 0
  Rational(input, other).to_r.rationalize(0.00001r)
end

Instance Method Details

#*(other) ⇒ Object



98
# File 'lib/income_tax/rate.rb', line 98

def *(other)   math(other,        &:*)   end

#**(other) ⇒ Object



100
# File 'lib/income_tax/rate.rb', line 100

def **(other)  math(other,        &:**)  end

#+(other) ⇒ Object



96
# File 'lib/income_tax/rate.rb', line 96

def +(other)   math(other,        &:+)   end

#-(other) ⇒ Object



97
# File 'lib/income_tax/rate.rb', line 97

def -(other)   math(other,        &:-)   end

#-@Object



92
93
94
# File 'lib/income_tax/rate.rb', line 92

def -@
  self.class.new(-preferred_representation)
end

#/(other) ⇒ Object



99
# File 'lib/income_tax/rate.rb', line 99

def /(other)   math(other,        &:/)   end

#<=>(other) ⇒ Object



101
# File 'lib/income_tax/rate.rb', line 101

def <=>(other) math(other, false, &:<=>) end

#==(other) ⇒ Object



107
108
109
110
# File 'lib/income_tax/rate.rb', line 107

def ==(other)
  return false unless other.is_a? Numeric
  super
end

#coerce(other) ⇒ Object



116
117
118
119
120
121
122
123
124
# File 'lib/income_tax/rate.rb', line 116

def coerce(other)
  case other
  when Rate       then [ other,                                 self                            ]
  when Rational   then [ other,                                 to_r                            ]
  when BigDecimal then [ other,                                 to_d                            ]
  when Integer    then [ other.public_send(preferred_coercion), public_send(preferred_coercion) ]
  else                 [ Float(other),                          to_f                            ]
  end
end

#eql?(other) ⇒ Boolean

Returns:

  • (Boolean)


103
104
105
# File 'lib/income_tax/rate.rb', line 103

def eql?(other)
  other.class == self.class and other == self
end

#gross(value) ⇒ Object



58
59
60
61
62
63
64
65
66
# File 'lib/income_tax/rate.rb', line 58

def gross(value)
  math(value) do |rate, net|
    if rate == 1
      net == 0 ? 0 : BigDecimal('Infinity')
    else
      net / (1 - rate)
    end
  end
end

#gross_taxes(value) ⇒ Object



74
75
76
# File 'lib/income_tax/rate.rb', line 74

def gross_taxes(value)
  self * value
end

#hashObject



112
113
114
# File 'lib/income_tax/rate.rb', line 112

def hash
  to_s.hash ^ to_d.hash
end

#inspectObject



88
89
90
# File 'lib/income_tax/rate.rb', line 88

def inspect
  "#<%p:%p>" % [ self.class, to_s ]
end

#net(value) ⇒ Object



68
69
70
71
72
# File 'lib/income_tax/rate.rb', line 68

def net(value)
  math(value) do |rate, gross|
    gross * (1 - rate)
  end
end

#net_taxes(value) ⇒ Object



78
79
80
81
82
# File 'lib/income_tax/rate.rb', line 78

def net_taxes(value)
  math(value) do |rate, net|
    rate == 1 ? net : net / (1 - rate) - net
  end
end

#preferred_representationObject



84
85
86
# File 'lib/income_tax/rate.rb', line 84

def preferred_representation
  send(@preferred_coercion)
end