Skip to content

Instantly share code, notes, and snippets.

@paraseba
Created April 28, 2012 20:29
Show Gist options
  • Save paraseba/2521789 to your computer and use it in GitHub Desktop.
Save paraseba/2521789 to your computer and use it in GitHub Desktop.
; Currencies know how to create Money
(defprotocol Currency
(make-money [this amount]))
; Money knows the details about how to print itself, round, etc.
; We want to be able to pass Moneys around, and after the fact, be able to
; print them, round them, etc.
(defprotocol Money
(str$ [this])
(round$ [this]))
;we want to save all registered currencies, to be able to display lists or whatever
;this could be a map to have find-currency functionality
(defonce ^:private all-currencies (atom []))
(defn register-currency [c]
(swap! all-currencies conj c))
(defn registered-currencies [] @all-currencies)
(defn make-currency [& {:as options}]
(doto
(reify Currency
(make-money [_ amount]
(reify Money
(round$ [_]
; we should do the real thing here
(let [decimal-points (:decimal-points options)
d (bigdec amount)]
(if (= decimal-points (.scale d))
d
(.setScale d decimal-points java.math.RoundingMode/HALF_UP))))
(str$ [this]
; we should do the real thing here
(let [ a (round$ this)
symbol (:symbol options)]
(if symbol
(if (:symbol-first options)
(str symbol a)
(str a " " symbol))
(str a )))))))
register-currency))
(def USD (make-currency
:symbol "$", :subunit "Cent", :name "United States Dollar",
:iso-code "USD", :iso-numeric "840", :subunit-to-unit 100,
:html-entity "$", :symbol-first true, :decimal-points 2 :priority 1))
(def ARS (make-currency
:symbol "$", :subunit "Centavo", :name "Argentine Peso",
:iso-code "ARS", :iso-numeric "032", :subunit-to-unit 100,
:html-entity "₱", :symbol-first true, :decimal-points 2 :priority 100))
(str$ (make-money USD 5)) ; => "$5.00"
(str$ (make-money ARS (* 5 4.41M))) ; => "$22.05"
(registered-currencies)
; => [#<user$make_currency$reify__935 user$make_currency$reify__935@15fec1d>
; #<user$make_currency$reify__935 user$make_currency$reify__935@4086649f>]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment