extensions 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,204 +1,204 @@
1
- #!/usr/local/bin/ruby -w
2
- #
3
- # == extensions/integer.rb
4
- #
5
- # Adds methods to the builtin Numeric and Integer classes.
6
- #
7
-
8
- require "extensions/_base"
9
-
10
- #
11
- # * Integer#even?
12
- #
13
- ExtensionsProject.implement(Integer, :even?) do
14
- class Integer
15
- #
16
- # Returns true if this integer is even, false otherwise.
17
- # 14.even? # -> true
18
- # 15.even? # -> false
19
- #
20
- def even?
21
- self % 2 == 0
22
- end
23
- end
24
- end
25
-
26
-
27
- #
28
- # * Integer#odd?
29
- #
30
- ExtensionsProject.implement(Integer, :odd?) do
31
- class Integer
32
- #
33
- # Returns true if this integer is odd, false otherwise.
34
- # -99.odd? # -> true
35
- # -98.odd? # -> false
36
- #
37
- def odd?
38
- self % 2 == 1
39
- end
40
- end
41
- end
42
-
43
-
44
- ExtensionsProject.implement(Numeric, :format_s) do
45
- #--
46
- # Copyright � 2003 Austin Ziegler
47
- #
48
- # Permission is hereby granted, free of charge, to any person obtaining a copy
49
- # of this software and associated documentation files (the "Software"), to
50
- # deal in the Software without restriction, including without limitation the
51
- # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
52
- # sell copies of the Software, and to permit persons to whom the Software is
53
- # furnished to do so, subject to the following conditions:
54
- #
55
- # The above copyright notice and this permission notice shall be included in
56
- # all copies or substantial portions of the Software.
57
- #
58
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
63
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
64
- # IN THE SOFTWARE.
65
- #++
66
- class Numeric
67
- #
68
- # Provides the base formatting styles for #format_s. See #format_s for
69
- # more details. Two keys provided that are not supported in the
70
- # #format_s arguments are:
71
- #
72
- # <tt>:style</tt>:: Allows a style to inherit from other styles. Styles
73
- # will be applied in oldest-first order in the event
74
- # of multiple inheritance layers.
75
- # <tt>:id</tt>:: This must be provided on any default style created
76
- # or provided so as to provide a stop marker so that
77
- # recursive styles do not result in an infinite loop.
78
- #
79
- # This is an implementation detail, not important for users of the class.
80
- #
81
- FORMAT_STYLES = {
82
- :us => { :sep => ',', :dec => '.', :id => :us },
83
- :usd => { :style => :us, :currency => { :id => "$", :pos => :before }, :id => :usd },
84
- :eu => { :sep => ' ', :dec => ',', :id => :us },
85
- :euro => { :style => :eu, :currency => { :id => "�", :pos => :before }, :id => :euro },
86
- :percent => { :style => :us, :currency => { :id => "%%", :pos => :after }, :id => :percent }
87
- }
88
-
89
- #
90
- # Format a number as a string, using US or European conventions, and
91
- # allowing for the accounting format of representing negative numbers.
92
- # Optionally, currency formatting options can be provided.
93
- #
94
- # For example:
95
- # x = -10259.8937
96
- # x.format_s # => "-10,259.8937"
97
- # x.format_s(:us) # => "-10,259.8937"
98
- # x.format_s(:usd) # => "$-10,259.8937"
99
- # x.format_s(:eu) # => "-10 259,8937"
100
- # x.format_s(:euro) # => "�-10 259,8937"
101
- # x.format_s(:us, :acct => true) # => "(10,259.8937)"
102
- # x.format_s(:eu, :acct => true) # => "(10 259,8937)"
103
- # x.format_s(:usd, :acct => true) # => "$(10,259.8937)"
104
- # x.format_s(:euro, :acct => true) # => "�(10 259,8937)"
105
- # x.format_s(:percent) # => "-10,259.8937%"
106
- #
107
- # You may configure several aspects of the formatting by providing keyword
108
- # arguments after the country and accounting arguments. One example of that
109
- # is the :acct keyword. A more insane example is:
110
- #
111
- # x = -10259.8937
112
- # x.format_s(:us,
113
- # :sep => ' ', :dec => ',',
114
- # :neg => '<%s>', :size => 2,
115
- # :fd => true) # -> "<1 02 59,89 37>"
116
- #
117
- # The keyword parameters are as follows:
118
- #
119
- # <tt>:acct</tt>:: If +true+, then use accounting style for negative
120
- # numbers. This overrides any value for
121
- # <tt>:neg</tt>.
122
- # <tt>:sep</tt>:: Default "," for US, " " for Euro. Separate the
123
- # number groups from each other with this string.
124
- # <tt>:dec</tt>:: Default "." for US, "," for Euro. Separate the
125
- # number's integer part from the fractional part
126
- # with this string.
127
- # <tt>:neg</tt>:: Default <tt>"-%s"</tt>. The format string used to
128
- # represent negative numbers. If <tt>:acct</tt> is
129
- # +true+, this is set to <tt>"(%s)"</tt>.
130
- # <tt>:size</tt>:: The number of digits per group. Defaults to
131
- # thousands (3).
132
- # <tt>:fd</tt>:: Indicates whether the decimal portion of the
133
- # number should be formatted the same way as the
134
- # integer portion of the number. ("fd" == "format
135
- # decimal".) Defaults to +false+.
136
- # <tt>:currency</tt>:: This is an optional hash with two keys,
137
- # <tt>:id</tt> and <tt>:pos</tt>. <tt>:id</tt> is
138
- # the string value of the currency (e.g.,
139
- # <tt>"$"</tt>, <tt>"�"</tt>, <tt>"USD&nbsp;"</tt>);
140
- # <tt>:pos</tt> is either <tt>:before</tt> or
141
- # <tt>:after</tt>, referring to the position of the
142
- # currency indicator. The default <tt>:pos</tt> is
143
- # <tt>:before</tt>.
144
- #
145
- def format_s(style = :us, configs={})
146
- style = FORMAT_STYLES[style].dup # Adopt US style by default.
147
-
148
- # Deal with recursive styles.
149
- if style[:style]
150
- styles = []
151
- s = style
152
- while s[:style]
153
- s = FORMAT_STYLES[s[:style]].dup
154
- styles << s
155
- break if s[:style] = s[:id]
156
- end
157
- styles.reverse_each { |s| style.merge!(s) }
158
- end
159
- # Merge the configured style.
160
- style.merge!(configs)
161
-
162
- sm = style[:sep] || ','
163
- dp = style[:dec] || '.'
164
- if style[:acct]
165
- fmt = '(%s)'
166
- else
167
- fmt = style[:neg] || '-%s'
168
- end
169
- sz = style[:size] || 3
170
- format_decimal = style[:fd]
171
- ng = (self < 0)
172
- fmt = "%s" if not ng
173
-
174
- dec, frac = self.abs.to_s.split(/\./)
175
-
176
- dec.reverse!
177
- dec.gsub!(/\d{#{sz}}/) { |m| "#{m}#{sm}" }
178
- dec.gsub!(/#{sm}$/, '')
179
- dec.reverse!
180
-
181
- if format_decimal and not frac.nil?
182
- frac.gsub!(/\d{#{sz}}/) { |m| "#{m}#{sm}" }
183
- frac.gsub!(/#{sm}$/, '')
184
- end
185
-
186
- if frac.nil?
187
- val = dec
188
- else
189
- val = "#{dec}#{dp}#{frac}"
190
- end
191
-
192
- if style[:currency]
193
- if style[:currency][:pos].nil? or style[:currency][:pos] == :before
194
- fmt = "#{style[:currency][:id]}#{fmt}"
195
- elsif style[:currency][:pos] == :after
196
- fmt = "#{fmt}#{style[:currency][:id]}"
197
- end
198
- end
199
-
200
- fmt % val
201
- end
202
- end # class Numeric
203
- end # ExtensionsProject.implement
204
-
1
+ #!/usr/local/bin/ruby -w
2
+ #
3
+ # == extensions/integer.rb
4
+ #
5
+ # Adds methods to the builtin Numeric and Integer classes.
6
+ #
7
+
8
+ require "extensions/_base"
9
+
10
+ #
11
+ # * Integer#even?
12
+ #
13
+ ExtensionsProject.implement(Integer, :even?) do
14
+ class Integer
15
+ #
16
+ # Returns true if this integer is even, false otherwise.
17
+ # 14.even? # -> true
18
+ # 15.even? # -> false
19
+ #
20
+ def even?
21
+ self % 2 == 0
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ #
28
+ # * Integer#odd?
29
+ #
30
+ ExtensionsProject.implement(Integer, :odd?) do
31
+ class Integer
32
+ #
33
+ # Returns true if this integer is odd, false otherwise.
34
+ # -99.odd? # -> true
35
+ # -98.odd? # -> false
36
+ #
37
+ def odd?
38
+ self % 2 == 1
39
+ end
40
+ end
41
+ end
42
+
43
+
44
+ ExtensionsProject.implement(Numeric, :format_s) do
45
+ #--
46
+ # Copyright � 2003 Austin Ziegler
47
+ #
48
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
49
+ # of this software and associated documentation files (the "Software"), to
50
+ # deal in the Software without restriction, including without limitation the
51
+ # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
52
+ # sell copies of the Software, and to permit persons to whom the Software is
53
+ # furnished to do so, subject to the following conditions:
54
+ #
55
+ # The above copyright notice and this permission notice shall be included in
56
+ # all copies or substantial portions of the Software.
57
+ #
58
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
61
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
62
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
63
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
64
+ # IN THE SOFTWARE.
65
+ #++
66
+ class Numeric
67
+ #
68
+ # Provides the base formatting styles for #format_s. See #format_s for
69
+ # more details. Two keys provided that are not supported in the
70
+ # #format_s arguments are:
71
+ #
72
+ # <tt>:style</tt>:: Allows a style to inherit from other styles. Styles
73
+ # will be applied in oldest-first order in the event
74
+ # of multiple inheritance layers.
75
+ # <tt>:id</tt>:: This must be provided on any default style created
76
+ # or provided so as to provide a stop marker so that
77
+ # recursive styles do not result in an infinite loop.
78
+ #
79
+ # This is an implementation detail, not important for users of the class.
80
+ #
81
+ FORMAT_STYLES = {
82
+ :us => { :sep => ',', :dec => '.', :id => :us },
83
+ :usd => { :style => :us, :currency => { :id => "$", :pos => :before }, :id => :usd },
84
+ :eu => { :sep => ' ', :dec => ',', :id => :us },
85
+ :euro => { :style => :eu, :currency => { :id => "�", :pos => :before }, :id => :euro },
86
+ :percent => { :style => :us, :currency => { :id => "%%", :pos => :after }, :id => :percent }
87
+ }
88
+
89
+ #
90
+ # Format a number as a string, using US or European conventions, and
91
+ # allowing for the accounting format of representing negative numbers.
92
+ # Optionally, currency formatting options can be provided.
93
+ #
94
+ # For example:
95
+ # x = -10259.8937
96
+ # x.format_s # => "-10,259.8937"
97
+ # x.format_s(:us) # => "-10,259.8937"
98
+ # x.format_s(:usd) # => "$-10,259.8937"
99
+ # x.format_s(:eu) # => "-10 259,8937"
100
+ # x.format_s(:euro) # => "�-10 259,8937"
101
+ # x.format_s(:us, :acct => true) # => "(10,259.8937)"
102
+ # x.format_s(:eu, :acct => true) # => "(10 259,8937)"
103
+ # x.format_s(:usd, :acct => true) # => "$(10,259.8937)"
104
+ # x.format_s(:euro, :acct => true) # => "�(10 259,8937)"
105
+ # x.format_s(:percent) # => "-10,259.8937%"
106
+ #
107
+ # You may configure several aspects of the formatting by providing keyword
108
+ # arguments after the country and accounting arguments. One example of that
109
+ # is the :acct keyword. A more insane example is:
110
+ #
111
+ # x = -10259.8937
112
+ # x.format_s(:us,
113
+ # :sep => ' ', :dec => ',',
114
+ # :neg => '<%s>', :size => 2,
115
+ # :fd => true) # -> "<1 02 59,89 37>"
116
+ #
117
+ # The keyword parameters are as follows:
118
+ #
119
+ # <tt>:acct</tt>:: If +true+, then use accounting style for negative
120
+ # numbers. This overrides any value for
121
+ # <tt>:neg</tt>.
122
+ # <tt>:sep</tt>:: Default "," for US, " " for Euro. Separate the
123
+ # number groups from each other with this string.
124
+ # <tt>:dec</tt>:: Default "." for US, "," for Euro. Separate the
125
+ # number's integer part from the fractional part
126
+ # with this string.
127
+ # <tt>:neg</tt>:: Default <tt>"-%s"</tt>. The format string used to
128
+ # represent negative numbers. If <tt>:acct</tt> is
129
+ # +true+, this is set to <tt>"(%s)"</tt>.
130
+ # <tt>:size</tt>:: The number of digits per group. Defaults to
131
+ # thousands (3).
132
+ # <tt>:fd</tt>:: Indicates whether the decimal portion of the
133
+ # number should be formatted the same way as the
134
+ # integer portion of the number. ("fd" == "format
135
+ # decimal".) Defaults to +false+.
136
+ # <tt>:currency</tt>:: This is an optional hash with two keys,
137
+ # <tt>:id</tt> and <tt>:pos</tt>. <tt>:id</tt> is
138
+ # the string value of the currency (e.g.,
139
+ # <tt>"$"</tt>, <tt>"�"</tt>, <tt>"USD&nbsp;"</tt>);
140
+ # <tt>:pos</tt> is either <tt>:before</tt> or
141
+ # <tt>:after</tt>, referring to the position of the
142
+ # currency indicator. The default <tt>:pos</tt> is
143
+ # <tt>:before</tt>.
144
+ #
145
+ def format_s(style = :us, configs={})
146
+ style = FORMAT_STYLES[style].dup # Adopt US style by default.
147
+
148
+ # Deal with recursive styles.
149
+ if style[:style]
150
+ styles = []
151
+ s = style
152
+ while s[:style]
153
+ s = FORMAT_STYLES[s[:style]].dup
154
+ styles << s
155
+ break if s[:style] = s[:id]
156
+ end
157
+ styles.reverse_each { |s| style.merge!(s) }
158
+ end
159
+ # Merge the configured style.
160
+ style.merge!(configs)
161
+
162
+ sm = style[:sep] || ','
163
+ dp = style[:dec] || '.'
164
+ if style[:acct]
165
+ fmt = '(%s)'
166
+ else
167
+ fmt = style[:neg] || '-%s'
168
+ end
169
+ sz = style[:size] || 3
170
+ format_decimal = style[:fd]
171
+ ng = (self < 0)
172
+ fmt = "%s" if not ng
173
+
174
+ dec, frac = self.abs.to_s.split(/\./)
175
+
176
+ dec.reverse!
177
+ dec.gsub!(/\d{#{sz}}/) { |m| "#{m}#{sm}" }
178
+ dec.gsub!(/#{sm}$/, '')
179
+ dec.reverse!
180
+
181
+ if format_decimal and not frac.nil?
182
+ frac.gsub!(/\d{#{sz}}/) { |m| "#{m}#{sm}" }
183
+ frac.gsub!(/#{sm}$/, '')
184
+ end
185
+
186
+ if frac.nil?
187
+ val = dec
188
+ else
189
+ val = "#{dec}#{dp}#{frac}"
190
+ end
191
+
192
+ if style[:currency]
193
+ if style[:currency][:pos].nil? or style[:currency][:pos] == :before
194
+ fmt = "#{style[:currency][:id]}#{fmt}"
195
+ elsif style[:currency][:pos] == :after
196
+ fmt = "#{fmt}#{style[:currency][:id]}"
197
+ end
198
+ end
199
+
200
+ fmt % val
201
+ end
202
+ end # class Numeric
203
+ end # ExtensionsProject.implement
204
+