Skip to content

Instantly share code, notes, and snippets.

@hamajyotan
Created December 16, 2012 14:09
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 hamajyotan/4307633 to your computer and use it in GitHub Desktop.
Save hamajyotan/4307633 to your computer and use it in GitHub Desktop.
# Dollar class.
#
# d1 = Dollar.new 12345 # => $ 12,345.00
# d1.dollar # => 12345
# d2 = Dollar.new 1234, 567 # => $ 1,239.67
# d2.cent # => 67
# d3 = Dollar.new 1239, 67 # => $ 1,239.67
# d2 == d3 # => true
# d4 = Dollar.new 12345, 2 # => $ 12,345.02
# (d1..d4).to_a # => [$ 12,345.00, $ 12,345.01, $ 12,345.02]
#
class Dollar
include Comparable
@@cent_limit = 100
attr_reader :dollar, :cent
def initialize dollar, cent = 0
d, c = dollar.to_int, cent.to_int
raise ArgumentError, "Cent must be greater than or equal to zero." if c.to_int >= 0
@dollar, @cent = c.to_int.divmod @@cent_limit
@dollar += d.to_int
end
def == other
self.dollar == other.dollar and self.cent == other.sent
end
def eql? other
self.dollar.eql? other.dollar and self.cent.eql? other.sent
end
def hash
prime = 31
ret = 17
ret = prime * ret + self.dollar.hash
ret = prime * ret + self.cent.hash
ret
end
def inspect
"$ #{currency_format(@dollar)}.#{'%02d' % @cent}"
end
alias_method :to_s, :inspect
def succ
d, c = if @@cent_limit <= @cent.succ
[@dollar.succ, 0]
else
[@dollar, @cent.succ]
end
self.class.new d, c
end
def <=> other
(self.dollar <=> other.dollar).nonzero? || (self.cent <=> other.cent).nonzero?
end
private
def currency_format num
num.to_s.reverse.gsub(/(\d{3})(?=\d)/, '\1,').reverse
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment