monetary_value 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/README.rdoc +6 -0
- data/Rakefile +11 -0
- data/lib/currency.rb +82 -0
- data/lib/monetary_value.rb +200 -0
- data/lib/monetary_value/version.rb +3 -0
- data/monetary_value.gemspec +23 -0
- data/test/currency_test.rb +9 -0
- data/test/monetary_value_test.rb +149 -0
- data/test/test_helper.rb +3 -0
- metadata +89 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.rdoc
ADDED
data/Rakefile
ADDED
data/lib/currency.rb
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'active_support/core_ext/enumerable' # Provides Enumerable#index_by
|
2
|
+
|
3
|
+
class Currency
|
4
|
+
attr_reader :id, :name, :code, :minor_divisor
|
5
|
+
|
6
|
+
def initialize(id, name, code, minor_divisor)
|
7
|
+
@id = id
|
8
|
+
@name = name
|
9
|
+
@code = code
|
10
|
+
@minor_divisor = minor_divisor
|
11
|
+
end
|
12
|
+
|
13
|
+
unless const_defined?(:CURRENCIES)
|
14
|
+
CURRENCIES = [
|
15
|
+
new(840, "United States Dollar", "USD", 100),
|
16
|
+
]
|
17
|
+
CURRENCIES_BY_ID = CURRENCIES.index_by(&:id)
|
18
|
+
CURRENCIES_BY_NAME = CURRENCIES.index_by(&:name)
|
19
|
+
CURRENCIES_BY_CODE = CURRENCIES.index_by(&:code)
|
20
|
+
|
21
|
+
CURRENCIES.freeze
|
22
|
+
CURRENCIES_BY_ID.freeze
|
23
|
+
CURRENCIES_BY_NAME.freeze
|
24
|
+
CURRENCIES_BY_CODE.freeze
|
25
|
+
end
|
26
|
+
|
27
|
+
def convert_to_minor_denomination(major_denomination)
|
28
|
+
return nil if major_denomination.nil?
|
29
|
+
(major_denomination.to_f * self.minor_divisor.to_f).round
|
30
|
+
end
|
31
|
+
|
32
|
+
def convert_to_major_denomination(minor_denomination)
|
33
|
+
return nil if minor_denomination.nil?
|
34
|
+
minor_denomination.to_f / self.minor_divisor.to_f
|
35
|
+
end
|
36
|
+
|
37
|
+
class << self
|
38
|
+
def all
|
39
|
+
CURRENCIES
|
40
|
+
end
|
41
|
+
|
42
|
+
def new(id = 840)
|
43
|
+
self[id]
|
44
|
+
end
|
45
|
+
|
46
|
+
def [](arg)
|
47
|
+
case arg
|
48
|
+
when Integer
|
49
|
+
CURRENCIES_BY_ID[arg]
|
50
|
+
else
|
51
|
+
raise ArgumentError, "invalid argument to Currency[]: #{arg.inspect}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def typecast(object)
|
56
|
+
return nil if object.nil?
|
57
|
+
return object if object.is_a? self
|
58
|
+
|
59
|
+
case object
|
60
|
+
when Integer
|
61
|
+
currency = CURRENCIES_BY_ID[object]
|
62
|
+
currency.nil? ? Currency.new : currency
|
63
|
+
when String
|
64
|
+
currency = CURRENCIES_BY_CODE[object]
|
65
|
+
currency.nil? ? Currency.new : currency
|
66
|
+
else
|
67
|
+
raise UntypecastableArgumentError, "#{object.inspect}:#{object.class} cannot be cast as #{self}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
def new_record?
|
74
|
+
false
|
75
|
+
end
|
76
|
+
|
77
|
+
def destroyed?
|
78
|
+
false
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'monetary_value/version'
|
2
|
+
|
3
|
+
require 'currency'
|
4
|
+
|
5
|
+
class MonetaryValue
|
6
|
+
attr_reader :currency, :denomination
|
7
|
+
|
8
|
+
def initialize(denomination = 0, currency = Currency.new)
|
9
|
+
@denomination = denomination
|
10
|
+
@currency = currency
|
11
|
+
end
|
12
|
+
|
13
|
+
# Backwards compatibility
|
14
|
+
# TODO: Remove minor_denomination from MonetaryValue
|
15
|
+
def minor_denomination
|
16
|
+
denomination
|
17
|
+
end
|
18
|
+
|
19
|
+
def major_denomination
|
20
|
+
"%01.2f" % (currency.convert_to_major_denomination(denomination))
|
21
|
+
end
|
22
|
+
|
23
|
+
# Display
|
24
|
+
def to_s(format = :default)
|
25
|
+
case format
|
26
|
+
when :default, :short
|
27
|
+
"$#{major_denomination}"
|
28
|
+
when :long
|
29
|
+
"#{major_denomination} #{currency.code}"
|
30
|
+
else
|
31
|
+
"$#{major_denomination}"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def inspect
|
36
|
+
to_s(:long)
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.parse(string)
|
40
|
+
currency = Currency.new
|
41
|
+
string.strip!
|
42
|
+
denomination = nil
|
43
|
+
nonnegative_string_formats = [
|
44
|
+
/^(\d+)$/, # "123"
|
45
|
+
/^\$(\d+)$/, # "$123"
|
46
|
+
/^(\d*)\.(\d{1,2})$/, # "123.4", ".4", "123.45", ".45"
|
47
|
+
/^\$(\d*)\.(\d{1,2})$/, # "$123.4", "$.4", "$123.45", "$.45"
|
48
|
+
]
|
49
|
+
|
50
|
+
nonnegative_string_formats.each do |format|
|
51
|
+
result = string.scan(format)
|
52
|
+
if result.size == 1
|
53
|
+
denominations = result.first
|
54
|
+
major_denomination = denominations[0].to_i
|
55
|
+
minor_denomination = denominations[1].nil? ? 0 : denominations[1].ljust(2, "0").to_i
|
56
|
+
denomination = major_denomination * 100 + minor_denomination
|
57
|
+
return MonetaryValue.new(denomination, currency)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
negative_string_formats = [
|
62
|
+
/^-(\d+)$/, # "-123"
|
63
|
+
/^-\$(\d+)$/, # "-$123"
|
64
|
+
/^\$-(\d+)$/, # "$-123"
|
65
|
+
/^-(\d*)\.(\d{1,2})$/, # "-123.4", "-.4", "-123.45", "-.45"
|
66
|
+
/^-\$(\d*)\.(\d{1,2})$/, # "-$123.4", "-$.4", "-$123.45", "-$.45"
|
67
|
+
/^\$-(\d*)\.(\d{1,2})$/, # "$-123.4", "$-.4", "$-123.45", "$-.45"
|
68
|
+
]
|
69
|
+
|
70
|
+
negative_string_formats.each do |format|
|
71
|
+
result = string.scan(format)
|
72
|
+
if result.size == 1
|
73
|
+
denominations = result.first
|
74
|
+
major_denomination = denominations[0].to_i
|
75
|
+
minor_denomination = denominations[1].nil? ? 0 : denominations[1].ljust(2, "0").to_i
|
76
|
+
denomination = major_denomination * 100 + minor_denomination
|
77
|
+
return MonetaryValue.new(-denomination, currency)
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
raise ArgumentError, "invalid money_value"
|
82
|
+
end
|
83
|
+
|
84
|
+
class << self
|
85
|
+
def typecast(object)
|
86
|
+
return nil if object.nil?
|
87
|
+
return object if object.is_a? self
|
88
|
+
|
89
|
+
case object
|
90
|
+
when String
|
91
|
+
begin
|
92
|
+
parse(object)
|
93
|
+
rescue ArgumentError => e
|
94
|
+
raise UntypecastableArgumentError, "#{object.inspect}:#{object.class} cannot be cast as #{self}"
|
95
|
+
end
|
96
|
+
else
|
97
|
+
raise UntypecastableArgumentError, "#{object.inspect}:#{object.class} cannot be cast as #{self}"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
##############
|
104
|
+
# Arithmetic #
|
105
|
+
##############
|
106
|
+
|
107
|
+
# Comparisons
|
108
|
+
include Comparable
|
109
|
+
def <=>(other)
|
110
|
+
raise ArgumentError, "can't compare values in difference currencies" unless self =~ other
|
111
|
+
denomination <=> other.denomination
|
112
|
+
end
|
113
|
+
|
114
|
+
# Addition
|
115
|
+
def +(other)
|
116
|
+
raise ArgumentError, "can't add values in difference currencies" unless self =~ other
|
117
|
+
MonetaryValue.new(denomination + other.denomination, currency)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Subtraction
|
121
|
+
def -(other)
|
122
|
+
raise ArgumentError, "can't subtract values in difference currencies" unless self =~ other
|
123
|
+
MonetaryValue.new(denomination - other.denomination, currency)
|
124
|
+
end
|
125
|
+
|
126
|
+
# Multiplication
|
127
|
+
def *(num)
|
128
|
+
MonetaryValue.new(denomination * num, currency)
|
129
|
+
end
|
130
|
+
|
131
|
+
# Division
|
132
|
+
def /(num)
|
133
|
+
MonetaryValue.new(denomination / num, currency)
|
134
|
+
end
|
135
|
+
|
136
|
+
# Absolute value
|
137
|
+
def abs
|
138
|
+
MonetaryValue.new(denomination.abs, currency)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Unary plus
|
142
|
+
def +@
|
143
|
+
MonetaryValue.new(denomination, currency)
|
144
|
+
end
|
145
|
+
|
146
|
+
# Unary minus
|
147
|
+
def -@
|
148
|
+
MonetaryValue.new(-denomination, currency)
|
149
|
+
end
|
150
|
+
|
151
|
+
# Currency matching
|
152
|
+
def =~(other)
|
153
|
+
currency == other.currency
|
154
|
+
end
|
155
|
+
|
156
|
+
# Next
|
157
|
+
def next
|
158
|
+
MonetaryValue.new(denomination.next, currency)
|
159
|
+
end
|
160
|
+
alias :succ :next
|
161
|
+
|
162
|
+
##############
|
163
|
+
# Sign tests #
|
164
|
+
##############
|
165
|
+
|
166
|
+
def zero?
|
167
|
+
denomination.zero?
|
168
|
+
end
|
169
|
+
|
170
|
+
def sign
|
171
|
+
denomination.sign
|
172
|
+
end
|
173
|
+
|
174
|
+
def positive?
|
175
|
+
denomination.positive?
|
176
|
+
end
|
177
|
+
|
178
|
+
def negative?
|
179
|
+
denomination.negative?
|
180
|
+
end
|
181
|
+
|
182
|
+
#################
|
183
|
+
# Serialization #
|
184
|
+
#################
|
185
|
+
|
186
|
+
def self.xml_root
|
187
|
+
"money"
|
188
|
+
end
|
189
|
+
|
190
|
+
def to_xml(options = {})
|
191
|
+
options[:root] ||= self.class.xml_root
|
192
|
+
{ :currency_id => currency.id, :denomination => denomination }.to_xml(options)
|
193
|
+
end
|
194
|
+
|
195
|
+
def self.from_xml(xml)
|
196
|
+
attributes = Hash.from_xml(xml)[xml_root].symbolize_keys
|
197
|
+
new( attributes[:denomination] || attributes[:minor_value], Currency.new(attributes[:currency_id]) )
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "monetary_value/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "monetary_value"
|
7
|
+
s.version = MonetaryValue::VERSION
|
8
|
+
s.authors = ["Ian James"]
|
9
|
+
s.email = ["ian@opencuro.com"]
|
10
|
+
s.homepage = "https://opencuro.com"
|
11
|
+
s.summary = %q{Library for working with monetary values}
|
12
|
+
s.description = %q{Provides the MonetaryValue and Currency classes.}
|
13
|
+
|
14
|
+
s.files = `git ls-files`.split("\n")
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
# specify any dependencies here; for example:
|
20
|
+
# s.add_development_dependency "rspec"
|
21
|
+
# s.add_runtime_dependency "rest-client"
|
22
|
+
s.add_dependency "activesupport"
|
23
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'monetary_value'
|
3
|
+
|
4
|
+
class MonetaryValueTest < ActiveSupport::TestCase
|
5
|
+
def test_parse
|
6
|
+
valid_strings = {
|
7
|
+
"0" => MonetaryValue.new(0),
|
8
|
+
"00" => MonetaryValue.new(0),
|
9
|
+
"1" => MonetaryValue.new(100),
|
10
|
+
"123" => MonetaryValue.new(12300),
|
11
|
+
|
12
|
+
"$0" => MonetaryValue.new(0),
|
13
|
+
"$00" => MonetaryValue.new(0),
|
14
|
+
"$1" => MonetaryValue.new(100),
|
15
|
+
"$123" => MonetaryValue.new(12300),
|
16
|
+
|
17
|
+
"0.00" => MonetaryValue.new(0),
|
18
|
+
"0.0" => MonetaryValue.new(0),
|
19
|
+
".00" => MonetaryValue.new(0),
|
20
|
+
".0" => MonetaryValue.new(0),
|
21
|
+
"0.12" => MonetaryValue.new(12),
|
22
|
+
"0.10" => MonetaryValue.new(10),
|
23
|
+
"0.1" => MonetaryValue.new(10),
|
24
|
+
".12" => MonetaryValue.new(12),
|
25
|
+
".10" => MonetaryValue.new(10),
|
26
|
+
".1" => MonetaryValue.new(10),
|
27
|
+
"1.23" => MonetaryValue.new(123),
|
28
|
+
"1.20" => MonetaryValue.new(120),
|
29
|
+
"1.2" => MonetaryValue.new(120),
|
30
|
+
|
31
|
+
"$0.00" => MonetaryValue.new(0),
|
32
|
+
"$0.0" => MonetaryValue.new(0),
|
33
|
+
"$.00" => MonetaryValue.new(0),
|
34
|
+
"$.0" => MonetaryValue.new(0),
|
35
|
+
"$0.12" => MonetaryValue.new(12),
|
36
|
+
"$0.10" => MonetaryValue.new(10),
|
37
|
+
"$0.1" => MonetaryValue.new(10),
|
38
|
+
"$.12" => MonetaryValue.new(12),
|
39
|
+
"$.10" => MonetaryValue.new(10),
|
40
|
+
"$.1" => MonetaryValue.new(10),
|
41
|
+
"$1.23" => MonetaryValue.new(123),
|
42
|
+
"$1.20" => MonetaryValue.new(120),
|
43
|
+
"$1.2" => MonetaryValue.new(120),
|
44
|
+
|
45
|
+
"-0" => MonetaryValue.new(0),
|
46
|
+
"-00" => MonetaryValue.new(0),
|
47
|
+
"-1" => MonetaryValue.new(-100),
|
48
|
+
"-123" => MonetaryValue.new(-12300),
|
49
|
+
|
50
|
+
"-$0" => MonetaryValue.new(0),
|
51
|
+
"-$00" => MonetaryValue.new(0),
|
52
|
+
"-$1" => MonetaryValue.new(-100),
|
53
|
+
"-$123" => MonetaryValue.new(-12300),
|
54
|
+
|
55
|
+
"$-0" => MonetaryValue.new(0),
|
56
|
+
"$-00" => MonetaryValue.new(0),
|
57
|
+
"$-1" => MonetaryValue.new(-100),
|
58
|
+
"$-123" => MonetaryValue.new(-12300),
|
59
|
+
|
60
|
+
"-0.00" => MonetaryValue.new(0),
|
61
|
+
"-0.0" => MonetaryValue.new(0),
|
62
|
+
"-.00" => MonetaryValue.new(0),
|
63
|
+
"-.0" => MonetaryValue.new(0),
|
64
|
+
"-0.12" => MonetaryValue.new(-12),
|
65
|
+
"-0.10" => MonetaryValue.new(-10),
|
66
|
+
"-0.1" => MonetaryValue.new(-10),
|
67
|
+
"-.12" => MonetaryValue.new(-12),
|
68
|
+
"-.10" => MonetaryValue.new(-10),
|
69
|
+
"-.1" => MonetaryValue.new(-10),
|
70
|
+
"-1.23" => MonetaryValue.new(-123),
|
71
|
+
"-1.20" => MonetaryValue.new(-120),
|
72
|
+
"-1.2" => MonetaryValue.new(-120),
|
73
|
+
|
74
|
+
"-$0.00" => MonetaryValue.new(0),
|
75
|
+
"-$0.0" => MonetaryValue.new(0),
|
76
|
+
"-$.00" => MonetaryValue.new(0),
|
77
|
+
"-$.0" => MonetaryValue.new(0),
|
78
|
+
"-$0.12" => MonetaryValue.new(-12),
|
79
|
+
"-$0.10" => MonetaryValue.new(-10),
|
80
|
+
"-$0.1" => MonetaryValue.new(-10),
|
81
|
+
"-$.12" => MonetaryValue.new(-12),
|
82
|
+
"-$.10" => MonetaryValue.new(-10),
|
83
|
+
"-$.1" => MonetaryValue.new(-10),
|
84
|
+
"-$1.23" => MonetaryValue.new(-123),
|
85
|
+
"-$1.20" => MonetaryValue.new(-120),
|
86
|
+
"-$1.2" => MonetaryValue.new(-120),
|
87
|
+
|
88
|
+
"$-0.00" => MonetaryValue.new(0),
|
89
|
+
"$-0.0" => MonetaryValue.new(0),
|
90
|
+
"$-.00" => MonetaryValue.new(0),
|
91
|
+
"$-.0" => MonetaryValue.new(0),
|
92
|
+
"$-0.12" => MonetaryValue.new(-12),
|
93
|
+
"$-0.10" => MonetaryValue.new(-10),
|
94
|
+
"$-0.1" => MonetaryValue.new(-10),
|
95
|
+
"$-.12" => MonetaryValue.new(-12),
|
96
|
+
"$-.10" => MonetaryValue.new(-10),
|
97
|
+
"$-.1" => MonetaryValue.new(-10),
|
98
|
+
"$-1.23" => MonetaryValue.new(-123),
|
99
|
+
"$-1.20" => MonetaryValue.new(-120),
|
100
|
+
"$-1.2" => MonetaryValue.new(-120),
|
101
|
+
|
102
|
+
}
|
103
|
+
|
104
|
+
valid_strings.each do |valid_string, result|
|
105
|
+
begin
|
106
|
+
assert_equal result, MonetaryValue.parse(valid_string), valid_string
|
107
|
+
rescue ArgumentError
|
108
|
+
flunk "#{valid_string} should be able to be parsed"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
invalid_strings = [
|
113
|
+
"",
|
114
|
+
"$",
|
115
|
+
".",
|
116
|
+
"$.",
|
117
|
+
|
118
|
+
"-",
|
119
|
+
"-$",
|
120
|
+
"$-",
|
121
|
+
"-.",
|
122
|
+
"-$.",
|
123
|
+
"$-.",
|
124
|
+
|
125
|
+
"$1.234",
|
126
|
+
"a1.23",
|
127
|
+
"1a.23",
|
128
|
+
"1. 23",
|
129
|
+
"1 .23",
|
130
|
+
"1,23",
|
131
|
+
"1.023",
|
132
|
+
"0x1",
|
133
|
+
|
134
|
+
"0.",
|
135
|
+
"1.",
|
136
|
+
"$0.",
|
137
|
+
"$-1.",
|
138
|
+
"-$1.",
|
139
|
+
]
|
140
|
+
|
141
|
+
invalid_strings.each do |invalid_string|
|
142
|
+
assert_raise ArgumentError do
|
143
|
+
MonetaryValue.parse(invalid_string)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: monetary_value
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 23
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
- 0
|
10
|
+
version: 1.0.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Ian James
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-06-06 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: activesupport
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Provides the MonetaryValue and Currency classes.
|
35
|
+
email:
|
36
|
+
- ian@opencuro.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- README.rdoc
|
47
|
+
- Rakefile
|
48
|
+
- lib/currency.rb
|
49
|
+
- lib/monetary_value.rb
|
50
|
+
- lib/monetary_value/version.rb
|
51
|
+
- monetary_value.gemspec
|
52
|
+
- test/currency_test.rb
|
53
|
+
- test/monetary_value_test.rb
|
54
|
+
- test/test_helper.rb
|
55
|
+
homepage: https://opencuro.com
|
56
|
+
licenses: []
|
57
|
+
|
58
|
+
post_install_message:
|
59
|
+
rdoc_options: []
|
60
|
+
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
hash: 3
|
69
|
+
segments:
|
70
|
+
- 0
|
71
|
+
version: "0"
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.8.10
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Library for working with monetary values
|
88
|
+
test_files: []
|
89
|
+
|