Skip to content

Commit

Permalink
Refactor Currency#new method
Browse files Browse the repository at this point in the history
  • Loading branch information
antstorm committed Jul 14, 2015
1 parent cf0b8af commit d271784
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 6 deletions.
10 changes: 5 additions & 5 deletions lib/money/currency.rb
Expand Up @@ -18,6 +18,7 @@ class Currency

# Keeping cached instances in sync between threads
@@mutex = Mutex.new
@@instances = {}

# Thrown when a Currency has been registered without all the attributes
# which are required for the current action.
Expand All @@ -34,18 +35,17 @@ def initialize(method, currency, attribute)
class UnknownCurrency < ArgumentError; end

class << self
alias_method :original_new, :new
def new(id)
id = id.to_s.downcase
unless stringified_keys.include?(id)
raise UnknownCurrency, "Unknown currency '#{id}'"
end

@@mutex.synchronize { instances[id] } || super
_instances[id] || @@mutex.synchronize { _instances[id] ||= super }
end

def instances
@instances ||= Hash.new { |h, k| h[k] = original_new(k) }
def _instances
@@instances
end

# Lookup a currency with given +id+ an returns a +Currency+ instance on
Expand Down Expand Up @@ -168,7 +168,7 @@ def stringified_keys
# @option delimiter [String] character between each thousands place
def register(curr)
key = curr.fetch(:iso_code).downcase.to_sym
@@mutex.synchronize { instances.delete(key.to_s) }
@@mutex.synchronize { _instances.delete(key.to_s) }
@table[key] = curr
@stringified_keys = stringify_keys
end
Expand Down
10 changes: 9 additions & 1 deletion spec/currency_spec.rb
Expand Up @@ -170,7 +170,8 @@ def to_s


describe "#initialize" do
before { Currency.instances.clear }
before { Currency._instances.clear }

it "lookups data from loaded config" do
currency = Currency.new("USD")
expect(currency.id).to eq :usd
Expand All @@ -185,6 +186,13 @@ def to_s
expect(currency.smallest_denomination).to eq 1
end

it 'caches instances' do
currency = Currency.new("USD")

expect(Currency._instances.length).to eq 1
expect(Currency._instances["usd"].object_id).to eq currency.object_id
end

it "raises UnknownCurrency with unknown currency" do
expect { Currency.new("xxx") }.to raise_error(Currency::UnknownCurrency, /xxx/)
end
Expand Down

0 comments on commit d271784

Please sign in to comment.