Class: Currency::Parser
Overview
This class parses a Money value from a String. Each Currency has a default Parser.
Constant Summary collapse
- @@default =
nil
- @@empty_hash =
{ }
Instance Attribute Summary collapse
-
#currency ⇒ Object
The default Currency to use if no Currency is specified.
-
#enforce_currency ⇒ Object
If true and a parsed string contains a ISO currency code that is not the same as currency, #parse() will raise IncompatibleCurrency.
-
#time ⇒ Object
The default Time to use if no Time is specified in the string.
Class Method Summary collapse
-
.default ⇒ Object
Get the default Formatter.
-
.default=(x) ⇒ Object
Set the default Formatter.
Instance Method Summary collapse
-
#_parse(str) ⇒ Object
:nodoc:.
-
#initialize(opt = { }) ⇒ Parser
constructor
A new instance of Parser.
-
#parse(str, opt = @@empty_hash) ⇒ Object
Parse a Money string in this Currency.
Constructor Details
#initialize(opt = { }) ⇒ Parser
Returns a new instance of Parser.
39 40 41 42 43 44 45 |
# File 'lib/currency/parser.rb', line 39 def initialize(opt = { }) @time = @enforce_currency = @currency = nil opt.each_pair{ | k, v | self.send("#{k}=", v) } end |
Instance Attribute Details
#currency ⇒ Object
The default Currency to use if no Currency is specified.
13 14 15 |
# File 'lib/currency/parser.rb', line 13 def currency @currency end |
#enforce_currency ⇒ Object
If true and a parsed string contains a ISO currency code that is not the same as currency, #parse() will raise IncompatibleCurrency. Defaults to false.
19 20 21 |
# File 'lib/currency/parser.rb', line 19 def enforce_currency @enforce_currency end |
#time ⇒ Object
The default Time to use if no Time is specified in the string. If :now, time is set to Time.new.
23 24 25 |
# File 'lib/currency/parser.rb', line 23 def time @time end |
Class Method Details
.default ⇒ Object
Get the default Formatter.
27 28 29 30 |
# File 'lib/currency/parser.rb', line 27 def self.default @@default ||= self.new end |
.default=(x) ⇒ Object
Set the default Formatter.
34 35 36 |
# File 'lib/currency/parser.rb', line 34 def self.default=(x) @@default = x end |
Instance Method Details
#_parse(str) ⇒ Object
:nodoc:
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/currency/parser.rb', line 48 def _parse(str) # :nodoc: x = str # Get currency. # puts "str = #{str.inspect}, @currency = #{@currency}" md = nil # match data # $stderr.puts "'#{x}'.Money_rep(#{self})" # Parse time. time = nil if (md = /(\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d(\.\d+)?Z)/.match(x)) time = Time.xmlschema(md[1]) unless time raise Currency::Exception::InvalidMoneyString, [ "time: #{str.inspect} #{currency} #{x.inspect}", :string, str, :currency, currency, :state, x, ] end x = md.pre_match + md.post_match end # Default time time ||= @time time = Time.new if time == :now # $stderr.puts "x = #{x}" convert_currency = nil # Handle currency code in string. if (md = /([A-Z][A-Z][A-Z])/.match(x)) curr = ::Currency::Currency.get(md[1]) x = md.pre_match + md.post_match if @currency && @currency != curr if @enforce_currency raise ::Currency::Exception::IncompatibleCurrency, [ "currency: #{str.inspect} #{@currency.code}", :string, str, :default_currency, @currency, :parsed_currency, curr, ] end convert_currency = @currency end currency = curr else currency = @currency || ::Currency::Currency.default currency = ::Currency::Currency.get(currency) end # Remove placeholders and symbol. x = x.gsub(/[, ]/, '') symbol = currency.symbol # FIXME x = x.gsub(symbol, '') if symbol # $stderr.puts "x = #{x.inspect}" # Match: whole Currency value. if md = /^([-+]?\d+)\.?$/.match(x) # $stderr.puts "'#{self}'.parse(#{str}) => EXACT" x = ::Currency::Money.new_rep(md[1].to_i * currency.scale, currency, @time) # Match: fractional Currency value. elsif md = /^([-+]?)(\d*)\.(\d+)$/.match(x) sign = md[1] whole = md[2] part = md[3] # $stderr.puts "'#{self}'.parse(#{str}) => DECIMAL (#{sign} #{whole} . #{part})" if part.length != currency.scale # Pad decimal places with additional '0' while part.length < currency.scale_exp part << '0' end # Truncate to Currency's decimal size. part = part[0 ... currency.scale_exp] # $stderr.puts " => INEXACT DECIMAL '#{whole}'" end # Put the string back together: # #{sign}#{whole}#{part} whole = sign + whole + part # $stderr.puts " => REP = #{whole}" x = whole.to_i x = ::Currency::Money.new_rep(x, currency, time) else # $stderr.puts "'#{self}'.parse(#{str}) => ??? '#{x}'" #x.to_f.Money_rep(self) raise ::Currency::Exception::InvalidMoneyString, [ "#{str.inspect} #{currency} #{x.inspect}", :string, str, :currency, currency, :state, x, ] end # Do conversion. if convert_currency x = x.convert(convert_currency) end x end |
#parse(str, opt = @@empty_hash) ⇒ Object
Parse a Money string in this Currency.
"123.45".money # Using default Currency.
=> USD $123.45
"$123.45 USD".money # Explicit Currency.
=> USD $123.45
"CAD 123.45".money
=> CAD $123.45
"123.45 CAD".money(:USD) # Incompatible explicit Currency.
!!! "123.45 CAD" USD (Currency::Exception::IncompatibleCurrency)
180 181 182 183 184 185 186 187 188 189 |
# File 'lib/currency/parser.rb', line 180 def parse(str, opt = @@empty_hash) prs = self unless opt.empty? prs = prs.clone opt.each_pair{ | k, v | prs.send("#{k}=", v) } end prs._parse(str) end |