stick 1.2.0 → 1.3.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/README +31 -42
- data/RELEASE +29 -0
- data/lib/stick/constants/cgs.rb +2 -2
- data/lib/stick/constants/typeless.rb +3 -0
- data/lib/stick/currency.rb +2 -0
- data/lib/stick/units.rb +5 -1
- data/lib/stick/units/base.rb +90 -89
- data/lib/stick/units/currency.rb +10 -9
- data/lib/stick/units/loaders.rb +3 -1
- data/lib/stick/units/units.rb +2 -0
- data/meta/MANIFEST +2 -0
- data/meta/ROLLRC +1 -1
- data/meta/project.yaml +1 -1
- data/test/test_currency.rb +1 -1
- data/test/test_units.rb +1 -1
- metadata +4 -6
- data/work/TODO +0 -20
- data/work/bytes.rb +0 -231
- data/work/multipliers.rb +0 -195
data/README
CHANGED
@@ -1,22 +1,26 @@
|
|
1
1
|
= STICK
|
2
2
|
|
3
|
+
http://rubyforge.org/projects/stick
|
4
|
+
|
3
5
|
STICK stands for Scientific Code Kit. It's main feature is the
|
4
|
-
a sophisticated SI units system.
|
6
|
+
a sophisticated SI units system. It also includes a large
|
7
|
+
set of natural constants and some extensions for the Matrix
|
8
|
+
class.
|
5
9
|
|
6
10
|
|
7
11
|
== Installation
|
8
12
|
|
9
13
|
You can install via Rubygems
|
10
14
|
|
11
|
-
|
15
|
+
gem install stick
|
12
16
|
|
13
17
|
or via tarball
|
14
18
|
|
15
19
|
tar -xzf stick-x.y.z.tar.gz
|
16
20
|
cd stick
|
17
|
-
sudo
|
21
|
+
sudo task/setup
|
18
22
|
|
19
|
-
(on Windows 'ruby
|
23
|
+
(on Windows 'ruby task/setup')
|
20
24
|
|
21
25
|
|
22
26
|
== Usage
|
@@ -44,67 +48,52 @@ the additional effect of making Units.with_unit_converter available
|
|
44
48
|
without the <code>Units.</code> prefix, as well as the shortcuts for
|
45
49
|
creating Units (see Units#method_missing).
|
46
50
|
|
47
|
-
=== Constants
|
48
51
|
|
49
|
-
|
50
|
-
The constants are stored in the Math::Constants module, but this
|
51
|
-
is included in Math for direct use by other Math libraries.
|
52
|
-
Math::Constants::CGS provides the constants in cm kg s format,
|
53
|
-
instead of the standard m kg s. Some examples...
|
52
|
+
=== Constants
|
54
53
|
|
55
|
-
|
54
|
+
Also included are a large assortment of real world contants. These come in two
|
55
|
+
varieties, typeless and typed via units.rb. (PLEASE NOTE: The typed variety is not
|
56
|
+
yet complete).
|
56
57
|
|
57
|
-
|
58
|
-
Math::CGS::SPEED_OF_LIGHT #=> 2.99792458e10
|
59
|
-
Math::Constants::SPEED_OF_LIGHT #=> 2.99792458e8
|
60
|
-
Math::Constants::CGS::SPEED_OF_LIGHT #=> 2.99792458e10
|
58
|
+
Constants are also provided in both mks (m kg s) and in cgs (cm g s) format.
|
61
59
|
|
62
|
-
|
60
|
+
require 'stick/constants/typeless_mks'
|
61
|
+
require 'stick/constants/typeless_cgs'
|
63
62
|
|
64
|
-
|
63
|
+
include Stick::Constants::Typeless
|
65
64
|
|
66
|
-
|
65
|
+
MKS::SPEED_OF_LIGHT #=> 2.99792458e8
|
66
|
+
CGS::SPEED_OF_LIGHT #=> 2.99792458e10
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
7.weekdays.ago
|
71
|
-
Time.now.next_year
|
68
|
+
Big thanks to Daniel Carrera and Brian Gough for their original work on Math::Constants
|
69
|
+
from which the typeless numbers derive.
|
72
70
|
|
73
71
|
|
74
72
|
=== Extensions to the Ruby's Matrix
|
75
73
|
|
76
|
-
|
77
|
-
|
78
|
-
The project consists of some enhancements to the Ruby "Matrix" module and includes: LU and QR (Householder, Givens, Gram Schmidt, Hessenberg) decompositions, bidiagonalization, eigenvalue and eigenvector calculations.
|
74
|
+
Also included are Matrix extensions by Cosmin Bonchis, which was done as a Google Summer of
|
75
|
+
Code 2007 project for Ruby Central Inc.
|
79
76
|
|
80
|
-
|
77
|
+
The library consists of some enhancements to the Ruby "Matrix" module and includes:
|
78
|
+
LU and QR (Householder, Givens, Gram Schmidt, Hessenberg) decompositions, bidiagonalization,
|
79
|
+
eigenvalue and eigenvector calculations.
|
81
80
|
|
82
|
-
|
81
|
+
This library is contatined in stick/matrix.rb, which also draws upon stick/mapcar.rb.
|
83
82
|
|
84
|
-
|
85
|
-
svn checkout http://matrix.rubyforge.org/svn/trunk/
|
83
|
+
This code can also be found on RubyForge at http://rubyforge.org/project/matrix.
|
86
84
|
|
87
85
|
|
88
86
|
== Authors/Contributors
|
89
87
|
|
90
|
-
* Peter Vanbroekhoven
|
88
|
+
* Peter Vanbroekhoven
|
91
89
|
* Thomas Sawyer
|
92
90
|
* Cosmin Bonchis
|
93
|
-
|
94
|
-
|
95
|
-
== Relevant URLs
|
96
|
-
|
97
|
-
Rubyforge project site:
|
98
|
-
|
99
|
-
http://rubyforge.org/projects/stick
|
100
|
-
|
101
|
-
Orginal Matrix extensions:
|
102
|
-
|
103
|
-
http://matrix.rubyforge.org/svn/trunk/
|
91
|
+
* Daniel Carrera
|
92
|
+
* Brian Gough
|
104
93
|
|
105
94
|
|
106
95
|
== License
|
107
96
|
|
108
|
-
Copyright 2006-2007 Peter Vanbroekhoven
|
97
|
+
Copyright 2006-2007 Peter Vanbroekhoven, Thomas Sawyer and Contributors
|
109
98
|
|
110
99
|
Ruby/GPL Licensed
|
data/RELEASE
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
I am happy to finally announce the initial public release of Stick,
|
2
|
+
the Scientific Code Kit for Ruby.
|
3
|
+
|
4
|
+
http://stick.rubyforge.org
|
5
|
+
|
6
|
+
Stick is a spin-off of Facets, based on the most excellent units.rb
|
7
|
+
library by Peter Vanbroekhoven. Units.rb, and its cousin currency.rb,
|
8
|
+
provide a very poweful system for working with typed values in a very
|
9
|
+
Ruby-esque way. For example:
|
10
|
+
|
11
|
+
10.m / 10.s #=> 1 m/s
|
12
|
+
1.bit/s + 8.bytes/s #=> 65.0 bit/s
|
13
|
+
1.mile.to(feet) #=> 5280.0 feet
|
14
|
+
1.acre.to(yd**2) #=> 4840.0 yd**2
|
15
|
+
|
16
|
+
In addition, the library contains a large collection of natural constants,
|
17
|
+
based on the original work of Daniel Carrera and Brian Gough; plus
|
18
|
+
Cosmin Bonchis' extensions to the Matrix class. In the future, we
|
19
|
+
expect to add a few more useful science and math oriented libraries.
|
20
|
+
|
21
|
+
Please note, despite the 1.x version number, this is still a bit of a nascent
|
22
|
+
release, as some functionality still needs address. In particular the
|
23
|
+
*typed* constants and currency conversions are not yet fully functional.
|
24
|
+
But the rest of the library works well. With any luck some of you will find
|
25
|
+
the project useful enough to offer a little time to help us polisih it up.
|
26
|
+
|
27
|
+
Thanks and enjoy,
|
28
|
+
|
29
|
+
Trans and Peter
|
data/lib/stick/constants/cgs.rb
CHANGED
@@ -35,11 +35,11 @@ require 'stick/units'
|
|
35
35
|
module Stick
|
36
36
|
module Constants
|
37
37
|
|
38
|
-
# = Constants in the CGS system (cm,
|
38
|
+
# = Constants in the CGS system (cm, g, s)
|
39
39
|
#
|
40
40
|
# Large assortment of real world contants. The constants are stored in
|
41
41
|
# the Math::Constants:CGS module. Math::Constants::CGS provides the
|
42
|
-
# constants in cm
|
42
|
+
# constants in cm g s format, opposed to the standard m kg s.
|
43
43
|
#
|
44
44
|
# == Synopsis
|
45
45
|
#
|
data/lib/stick/currency.rb
CHANGED
data/lib/stick/units.rb
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
require 'stick/units/units'
|
2
2
|
|
3
3
|
module Stick
|
4
|
+
module Units
|
5
|
+
|
4
6
|
# Load conversion units.
|
5
7
|
class Converter
|
6
8
|
require("units-standard")
|
7
9
|
end
|
10
|
+
|
11
|
+
end
|
8
12
|
end
|
9
13
|
|
10
14
|
|
@@ -14,7 +18,7 @@ end
|
|
14
18
|
|
15
19
|
class A
|
16
20
|
|
17
|
-
include ::Units
|
21
|
+
include Stick::Units
|
18
22
|
|
19
23
|
def test
|
20
24
|
puts 1.bit/s + 8.bytes/s
|
data/lib/stick/units/base.rb
CHANGED
@@ -70,14 +70,15 @@ end
|
|
70
70
|
#++
|
71
71
|
|
72
72
|
module Stick
|
73
|
+
module Units
|
73
74
|
|
74
75
|
def method_missing(m, *args, &blk)
|
75
76
|
if args.length == 1
|
76
|
-
args[0] = (::Stick::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Converter
|
77
|
-
return ::Stick::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
|
78
|
-
elsif (::Stick::Converter.current.registered?(m) rescue false)
|
77
|
+
args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
|
78
|
+
return ::Stick::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
|
79
|
+
elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
|
79
80
|
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
|
80
|
-
return ::Stick::Unit.new({m => 1}, ::Stick::Converter.current)
|
81
|
+
return ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current)
|
81
82
|
end
|
82
83
|
::Exception.with_clean_backtrace("method_missing") {
|
83
84
|
super
|
@@ -85,8 +86,8 @@ module Stick
|
|
85
86
|
end
|
86
87
|
|
87
88
|
def const_missing(c)
|
88
|
-
if (::Stick::Converter.current.registered?(c) rescue false)
|
89
|
-
return ::Stick::Unit.new({c => 1}, ::Stick::Converter.current)
|
89
|
+
if (::Stick::Units::Converter.current.registered?(c) rescue false)
|
90
|
+
return ::Stick::Units::Unit.new({c => 1}, ::Stick::Units::Converter.current)
|
90
91
|
else
|
91
92
|
::Exception.with_clean_backtrace("const_missing") {
|
92
93
|
super
|
@@ -95,7 +96,7 @@ module Stick
|
|
95
96
|
end
|
96
97
|
|
97
98
|
def self.append_features(m)
|
98
|
-
m.send(:extend, ::Stick)
|
99
|
+
m.send(:extend, ::Stick::Units)
|
99
100
|
super
|
100
101
|
end
|
101
102
|
|
@@ -116,7 +117,7 @@ module Stick
|
|
116
117
|
#
|
117
118
|
# See also Converter.current.
|
118
119
|
def with_unit_converter(name, &blk) # :yields:
|
119
|
-
::Stick::Converter.with_converter(name, &blk)
|
120
|
+
::Stick::Units::Converter.with_converter(name, &blk)
|
120
121
|
end
|
121
122
|
|
122
123
|
module_function :with_unit_converter
|
@@ -137,7 +138,7 @@ module Stick
|
|
137
138
|
|
138
139
|
attr_reader :name, :converter
|
139
140
|
|
140
|
-
def initialize(name, converter = ::Stick::Converter.current)
|
141
|
+
def initialize(name, converter = ::Stick::Units::Converter.current)
|
141
142
|
name = name.to_sym
|
142
143
|
raise ::ArgumentError, "unit #{name.to_s.dump} not registered with #{converter}" if not converter.registered? name
|
143
144
|
@name = name
|
@@ -149,7 +150,7 @@ module Stick
|
|
149
150
|
end
|
150
151
|
|
151
152
|
def ==(other)
|
152
|
-
other.is_a?(::Stick::BaseUnit) && other.name == @name && other.converter == @converter
|
153
|
+
other.is_a?(::Stick::Units::BaseUnit) && other.name == @name && other.converter == @converter
|
153
154
|
end
|
154
155
|
|
155
156
|
alias eql? ==
|
@@ -159,7 +160,7 @@ module Stick
|
|
159
160
|
end
|
160
161
|
|
161
162
|
def to_s
|
162
|
-
if ::Stick::Converter.current.includes?(converter)
|
163
|
+
if ::Stick::Units::Converter.current.includes?(converter)
|
163
164
|
@name.to_s
|
164
165
|
else
|
165
166
|
"#{@converter}:#{@name}"
|
@@ -202,13 +203,13 @@ module Stick
|
|
202
203
|
#
|
203
204
|
# See also Converter, Converter.converter
|
204
205
|
def initialize(units = {}, converter = nil)
|
205
|
-
conv = proc { converter ||= ::Stick::Converter.current }
|
206
|
+
conv = proc { converter ||= ::Stick::Units::Converter.current }
|
206
207
|
if units.is_a? ::String
|
207
208
|
@units = decode_string(units, conv)
|
208
209
|
else
|
209
210
|
@units = {}
|
210
211
|
units.each_pair do |k, v|
|
211
|
-
k = conv[].base_unit(k.to_sym) if not k.is_a? ::Stick::BaseUnit
|
212
|
+
k = conv[].base_unit(k.to_sym) if not k.is_a? ::Stick::Units::BaseUnit
|
212
213
|
@units[k] = v
|
213
214
|
end
|
214
215
|
end
|
@@ -221,7 +222,7 @@ module Stick
|
|
221
222
|
@units.each_pair do |u, e|
|
222
223
|
result[u] = e * p
|
223
224
|
end
|
224
|
-
::Stick::Unit.new(result)
|
225
|
+
::Stick::Units::Unit.new(result)
|
225
226
|
end
|
226
227
|
|
227
228
|
# Multiplies with the given Unit.
|
@@ -240,18 +241,18 @@ module Stick
|
|
240
241
|
end
|
241
242
|
|
242
243
|
def coerce(other) # :nodoc:
|
243
|
-
return [::Stick::Unit.new({}), self] if other == 1
|
244
|
-
::Stick::Converter.coerce_units(self, other)
|
244
|
+
return [::Stick::Units::Unit.new({}), self] if other == 1
|
245
|
+
::Stick::Units::Converter.coerce_units(self, other)
|
245
246
|
end
|
246
247
|
|
247
248
|
def simplify
|
248
|
-
::Stick::Converter.simplify_unit(self)
|
249
|
+
::Stick::Units::Converter.simplify_unit(self)
|
249
250
|
end
|
250
251
|
|
251
|
-
# Returns +true+ iff the two
|
252
|
+
# Returns +true+ iff the two units are equals, <i>i.e.,</i> iff they have
|
252
253
|
# the same exponent for all units, and they both use the same Converter.
|
253
254
|
def ==(other)
|
254
|
-
other.is_a?(::Stick::Unit) && other.units == units
|
255
|
+
other.is_a?(::Stick::Units::Unit) && other.units == units
|
255
256
|
end
|
256
257
|
|
257
258
|
alias eql? ==
|
@@ -264,7 +265,7 @@ module Stick
|
|
264
265
|
# Unit. This is less strict than equality because for example hours are
|
265
266
|
# compatible with seconds ("we can add them"), but hours are not seconds.
|
266
267
|
def compatible_with?(other)
|
267
|
-
conv1, conv2 = ::Stick::Converter.coerce_units(self, other)
|
268
|
+
conv1, conv2 = ::Stick::Units::Converter.coerce_units(self, other)
|
268
269
|
conv1.units == conv2.units
|
269
270
|
end
|
270
271
|
|
@@ -288,11 +289,11 @@ module Stick
|
|
288
289
|
|
289
290
|
def method_missing(m, *args, &blk)
|
290
291
|
if args.length == 1
|
291
|
-
args[0] = (::Stick::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Converter
|
292
|
-
return self * ::Stick::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
|
293
|
-
elsif (::Stick::Converter.current.registered?(m) rescue false)
|
292
|
+
args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
|
293
|
+
return self * ::Stick::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
|
294
|
+
elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
|
294
295
|
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
|
295
|
-
return self * ::Stick::Unit.new({m => 1}, ::Stick::Converter.current)
|
296
|
+
return self * ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current)
|
296
297
|
end
|
297
298
|
::Exception.with_clean_backtrace("method_missing") {
|
298
299
|
super
|
@@ -302,7 +303,7 @@ module Stick
|
|
302
303
|
private
|
303
304
|
|
304
305
|
def decode_string(s, converter)
|
305
|
-
if ::Stick::Regexps::TOTAL_UNIT_REGEXP =~ s
|
306
|
+
if ::Stick::Units::Regexps::TOTAL_UNIT_REGEXP =~ s
|
306
307
|
numerator, denominator = $1, $2
|
307
308
|
units = {}
|
308
309
|
decode_multiplicative_string(numerator, 1, converter, units) if numerator
|
@@ -316,9 +317,9 @@ module Stick
|
|
316
317
|
end
|
317
318
|
|
318
319
|
def decode_multiplicative_string(s, multiplier, converter, result)
|
319
|
-
s.scan(::Stick::Regexps::SINGLE_UNIT_REGEXP) do |conv, unit, exp|
|
320
|
+
s.scan(::Stick::Units::Regexps::SINGLE_UNIT_REGEXP) do |conv, unit, exp|
|
320
321
|
if unit
|
321
|
-
conv = ::Stick::Converter.converter(conv)
|
322
|
+
conv = ::Stick::Units::Converter.converter(conv)
|
322
323
|
else
|
323
324
|
conv, unit = converter[], conv
|
324
325
|
end
|
@@ -336,13 +337,13 @@ module Stick
|
|
336
337
|
|
337
338
|
def do_op(op, dual_op, other)
|
338
339
|
other = other.to_unit
|
339
|
-
raise TypeError, "cannot convert to Unit" unless ::Stick::Unit === other
|
340
|
+
raise TypeError, "cannot convert to Unit" unless ::Stick::Units::Unit === other
|
340
341
|
result = @units.dup
|
341
342
|
other.units.each_pair do |u, e|
|
342
343
|
result[u] = 0 if not result[u]
|
343
344
|
result[u] = result[u].send(dual_op, e)
|
344
345
|
end
|
345
|
-
::Stick::Unit.new(result)
|
346
|
+
::Stick::Units::Unit.new(result)
|
346
347
|
end
|
347
348
|
|
348
349
|
end
|
@@ -353,9 +354,9 @@ module Stick
|
|
353
354
|
#
|
354
355
|
# A Value can be added to, subtracted from and multiplied with another value,
|
355
356
|
# though only when both Values are using the same Converter. While multiplication
|
356
|
-
# is always possible, adding or subtracting values with incompatible
|
357
|
-
# results in a TypeError. When two
|
358
|
-
# the Value with the larger of the
|
357
|
+
# is always possible, adding or subtracting values with incompatible units
|
358
|
+
# results in a TypeError. When two units are compatible but not the same,
|
359
|
+
# the Value with the larger of the units is converted to the smaller of the units.
|
359
360
|
# For example adding 100 seconds and 1 minute, the latter is converted to 60 seconds
|
360
361
|
# because a second is smaller than a minute. The result is 160 seconds.
|
361
362
|
class Value < Numeric
|
@@ -413,7 +414,7 @@ module Stick
|
|
413
414
|
%w{ * / }.each do |op|
|
414
415
|
eval %{
|
415
416
|
def #{op}(other)
|
416
|
-
::Stick::Value.new(*do_multiplicative_op(:#{op}, other))
|
417
|
+
::Stick::Units::Value.new(*do_multiplicative_op(:#{op}, other))
|
417
418
|
end
|
418
419
|
}
|
419
420
|
end
|
@@ -421,14 +422,14 @@ module Stick
|
|
421
422
|
%w{ + - modulo remainder % }.each do |op|
|
422
423
|
eval %{
|
423
424
|
def #{op}(other)
|
424
|
-
::Stick::Value.new(*do_additive_op(:#{op}, other))
|
425
|
+
::Stick::Units::Value.new(*do_additive_op(:#{op}, other))
|
425
426
|
end
|
426
427
|
}
|
427
428
|
end
|
428
429
|
|
429
430
|
def divmod(other)
|
430
431
|
(q, r), unit = *do_additive_op(:divmod, other)
|
431
|
-
[q, ::Stick::Value.new(r, unit)]
|
432
|
+
[q, ::Stick::Units::Value.new(r, unit)]
|
432
433
|
end
|
433
434
|
|
434
435
|
def div(other)
|
@@ -444,7 +445,7 @@ module Stick
|
|
444
445
|
end
|
445
446
|
|
446
447
|
def **(other) # :nodoc:
|
447
|
-
::Stick::Value.new(@value ** other, @unit ** other)
|
448
|
+
::Stick::Units::Value.new(@value ** other, @unit ** other)
|
448
449
|
end
|
449
450
|
|
450
451
|
def <=>(other) # :nodoc:
|
@@ -466,7 +467,7 @@ module Stick
|
|
466
467
|
%w{ abs ceil floor next round succ truncate }.each do |op|
|
467
468
|
eval %{
|
468
469
|
def #{op}
|
469
|
-
::Stick::Value.new(@value.#{op}, @unit)
|
470
|
+
::Stick::Units::Value.new(@value.#{op}, @unit)
|
470
471
|
end
|
471
472
|
}
|
472
473
|
end
|
@@ -482,20 +483,20 @@ module Stick
|
|
482
483
|
# Converts this Value to the given Unit.
|
483
484
|
# This only works if the Converters used by this Value's Unit
|
484
485
|
# and the given Unit are the same. It obviously fails if the
|
485
|
-
#
|
486
|
+
# Units are not compatible (can't add apples and oranges).
|
486
487
|
def to(to_unit, converter = nil)
|
487
488
|
raise ArgumentError, "Wrong number of arguments" if converter && !(::String === to_unit)
|
488
489
|
to_unit = to_unit.to_unit(converter)
|
489
|
-
raise TypeError, "cannot convert to Unit" unless ::Stick::Unit === to_unit
|
490
|
+
raise TypeError, "cannot convert to Unit" unless ::Stick::Units::Unit === to_unit
|
490
491
|
conv1, conv2 = unit.coerce(to_unit)
|
491
492
|
raise TypeError, "incompatible units for operation" if conv1.units != conv2.units
|
492
493
|
mult = conv1.multiplier / conv2.multiplier
|
493
|
-
::Stick::Value.new(value * mult, to_unit)
|
494
|
+
::Stick::Units::Value.new(value * mult, to_unit)
|
494
495
|
end
|
495
496
|
|
496
497
|
def coerce(other) # :nodoc:
|
497
498
|
if ::Numeric === other
|
498
|
-
[::Stick::Value.new!(other, ::Stick::Unit.new), self]
|
499
|
+
[::Stick::Units::Value.new!(other, ::Stick::Units::Unit.new), self]
|
499
500
|
else
|
500
501
|
super
|
501
502
|
end
|
@@ -510,7 +511,7 @@ module Stick
|
|
510
511
|
# exception otherwise.
|
511
512
|
def to_f
|
512
513
|
val = simplify
|
513
|
-
if ::Stick::Value === val
|
514
|
+
if ::Stick::Units::Value === val
|
514
515
|
raise TypeError, "Cannot convert to float"
|
515
516
|
else
|
516
517
|
val.to_f
|
@@ -521,7 +522,7 @@ module Stick
|
|
521
522
|
# exception otherwise.
|
522
523
|
def to_i
|
523
524
|
val = simplify
|
524
|
-
if ::Stick::Value === val
|
525
|
+
if ::Stick::Units::Value === val
|
525
526
|
raise TypeError, "Cannot convert to integer"
|
526
527
|
else
|
527
528
|
val.to_i
|
@@ -532,7 +533,7 @@ module Stick
|
|
532
533
|
# exception otherwise.
|
533
534
|
def to_int
|
534
535
|
val = simplify
|
535
|
-
if ::Stick::Value === val
|
536
|
+
if ::Stick::Units::Value === val
|
536
537
|
raise TypeError, "Cannot convert to integer"
|
537
538
|
else
|
538
539
|
val.to_int
|
@@ -546,7 +547,7 @@ module Stick
|
|
546
547
|
if new_unit.unitless?
|
547
548
|
@value * mul
|
548
549
|
else
|
549
|
-
::Stick::Value.new(@value * mul, new_unit)
|
550
|
+
::Stick::Units::Value.new(@value * mul, new_unit)
|
550
551
|
end
|
551
552
|
end
|
552
553
|
|
@@ -559,11 +560,11 @@ module Stick
|
|
559
560
|
|
560
561
|
def method_missing(m, *args, &blk)
|
561
562
|
if args.length == 1
|
562
|
-
args[0] = (::Stick::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Converter
|
563
|
-
return self * ::Stick::Value.new(1, ::Stick::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
|
564
|
-
elsif (::Stick::Converter.current.registered?(m) rescue false)
|
563
|
+
args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
|
564
|
+
return self * ::Stick::Units::Value.new(1, ::Stick::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
|
565
|
+
elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
|
565
566
|
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
|
566
|
-
return self * ::Stick::Value.new(1, ::Stick::Unit.new({m => 1}, ::Stick::Converter.current))
|
567
|
+
return self * ::Stick::Units::Value.new(1, ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current))
|
567
568
|
end
|
568
569
|
::Exception.with_clean_backtrace("method_missing") {
|
569
570
|
super
|
@@ -573,9 +574,9 @@ module Stick
|
|
573
574
|
private
|
574
575
|
|
575
576
|
def self.decode_string(s, converter)
|
576
|
-
if m = ::Stick::Regexps::VALUE_REGEXP.match(s)
|
577
|
+
if m = ::Stick::Units::Regexps::VALUE_REGEXP.match(s)
|
577
578
|
value = m[2].empty? ? Integer(m[1]) : Float(m[1])
|
578
|
-
unit = ::Stick::Unit.new(m[3], converter)
|
579
|
+
unit = ::Stick::Units::Unit.new(m[3], converter)
|
579
580
|
[value, unit]
|
580
581
|
else
|
581
582
|
raise ::ArgumentError, "Illegal value string #{s.dump}"
|
@@ -584,8 +585,8 @@ module Stick
|
|
584
585
|
|
585
586
|
def do_additive_op(op, other)
|
586
587
|
other = other.to_value
|
587
|
-
raise TypeError, "cannot convert to Value" unless ::Stick::Value === other
|
588
|
-
if other.is_a? ::Stick::Value
|
588
|
+
raise TypeError, "cannot convert to Value" unless ::Stick::Units::Value === other
|
589
|
+
if other.is_a? ::Stick::Units::Value
|
589
590
|
conv1, conv2 = unit.coerce(other.unit)
|
590
591
|
raise TypeError, "incompatible units for #{op}" if conv1.units != conv2.units
|
591
592
|
mult = conv2.multiplier / conv1.multiplier
|
@@ -602,9 +603,9 @@ module Stick
|
|
602
603
|
|
603
604
|
def do_multiplicative_op(op, other)
|
604
605
|
case other
|
605
|
-
when ::Stick::Value
|
606
|
+
when ::Stick::Units::Value
|
606
607
|
[value.send(op, other.value), unit.send(op, other.unit)]
|
607
|
-
when ::Stick::Unit
|
608
|
+
when ::Stick::Units::Unit
|
608
609
|
[value, unit.send(op, other)]
|
609
610
|
when ::Numeric
|
610
611
|
[value.send(op, other), unit]
|
@@ -613,19 +614,19 @@ module Stick
|
|
613
614
|
# Problem : how check whether to_value failed without
|
614
615
|
# masking all exceptions?
|
615
616
|
other = other.to_value
|
616
|
-
raise TypeError, "cannot convert to Value" unless ::Stick::Value === other
|
617
|
+
raise TypeError, "cannot convert to Value" unless ::Stick::Units::Value === other
|
617
618
|
do_multiplicative_op(op, other)
|
618
619
|
end
|
619
620
|
end
|
620
621
|
|
621
622
|
end
|
622
623
|
|
623
|
-
# This class handles all conversions between
|
624
|
+
# This class handles all conversions between units.
|
624
625
|
#
|
625
|
-
# There are two kinds of
|
626
|
-
# of other
|
627
|
-
# as a function of other
|
628
|
-
# registered specifying how it depends on other
|
626
|
+
# There are two kinds of units; those that are not expressed as a function
|
627
|
+
# of other units --called base units-- and those that are expressed
|
628
|
+
# as a function of other units --called derived units. The latter kind is
|
629
|
+
# registered specifying how it depends on other units, while the former
|
629
630
|
# kind is not.
|
630
631
|
#
|
631
632
|
# This class also registers a list of Converters that are generally useable.
|
@@ -672,7 +673,7 @@ module Stick
|
|
672
673
|
# Included the given converter in the receiver, unless it
|
673
674
|
# was already included.
|
674
675
|
def include(conv)
|
675
|
-
conv = ::Stick::Converter.converter(conv) if not conv.is_a?(::Stick::Converter)
|
676
|
+
conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::Units::Converter)
|
676
677
|
raise "Circular include" if conv.includes?(self)
|
677
678
|
@included << conv if not includes? conv
|
678
679
|
self
|
@@ -681,7 +682,7 @@ module Stick
|
|
681
682
|
# Returns whether the given converter was included in the
|
682
683
|
# receiver.
|
683
684
|
def includes?(conv)
|
684
|
-
conv = ::Stick::Converter.converter(conv) if not conv.is_a?(::Stick::Converter)
|
685
|
+
conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::Units::Converter)
|
685
686
|
return true if conv == self
|
686
687
|
@included.each do |c|
|
687
688
|
return true if conv == c || c.includes?(conv)
|
@@ -713,7 +714,7 @@ module Stick
|
|
713
714
|
# Returns the base unit with this name
|
714
715
|
def base_unit(name)
|
715
716
|
if conv = registered?(name)
|
716
|
-
return ::Stick::BaseUnit.new(name, conv)
|
717
|
+
return ::Stick::Units::BaseUnit.new(name, conv)
|
717
718
|
end
|
718
719
|
raise "unit #{name.to_s.dump} not registered with #{self}"
|
719
720
|
end
|
@@ -727,7 +728,7 @@ module Stick
|
|
727
728
|
def method_missing(m, *args, &blk)
|
728
729
|
if registered?(m)
|
729
730
|
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
|
730
|
-
return ::Stick::Unit.new({m => 1}, self)
|
731
|
+
return ::Stick::Units::Unit.new({m => 1}, self)
|
731
732
|
end
|
732
733
|
::Exception.with_clean_backtrace("method_missing") {
|
733
734
|
super
|
@@ -750,7 +751,7 @@ module Stick
|
|
750
751
|
# The differences with aliases is that prefixes work differently;
|
751
752
|
# see +register_si_unit+, +register_binary_unit+ and
|
752
753
|
# +register_binary_iec_unit+.
|
753
|
-
# +equals+:: If present, specifies how the Unit depends on other
|
754
|
+
# +equals+:: If present, specifies how the Unit depends on other units.
|
754
755
|
# The value for this key can either be a Hash with +unit+ mapping to
|
755
756
|
# a Unit and +multiplier+ mapping to a numeric multiplier, or
|
756
757
|
# a String containing the multiplier, followed by a space, followed by
|
@@ -793,12 +794,12 @@ module Stick
|
|
793
794
|
abbrev = info[:abbrev]
|
794
795
|
multiplier = info[:multiplier] || 1
|
795
796
|
power = info[:power] || 1
|
796
|
-
register_unit(pre + unit, :equals => {:unit => ::Stick::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
797
|
+
register_unit(pre + unit, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
797
798
|
aliases.each do |a|
|
798
|
-
register_unit(pre + a, :equals => {:unit => ::Stick::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
799
|
+
register_unit(pre + a, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
799
800
|
end
|
800
801
|
abbrevs.each do |a|
|
801
|
-
register_unit(abbrev + a, :equals => {:unit => ::Stick::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
802
|
+
register_unit(abbrev + a, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
|
802
803
|
end
|
803
804
|
end
|
804
805
|
end
|
@@ -819,9 +820,9 @@ module Stick
|
|
819
820
|
:multiplier => data[:multiplier] || data['multiplier']}
|
820
821
|
end
|
821
822
|
if /^\s*1\s*\// =~ data
|
822
|
-
{:unit => ::Stick::Unit.new(data, self)}
|
823
|
-
elsif m = /^\s*#{::Stick::Regexps::NUMBER_REGEXP}(?:\s+(\S.*)$|\s*$)/.match(data)
|
824
|
-
unit = m[3] ? ::Stick::Unit.new(m[3], self) : ::Stick::Unit.new({}, self)
|
823
|
+
{:unit => ::Stick::Units::Unit.new(data, self)}
|
824
|
+
elsif m = /^\s*#{::Stick::Units::Regexps::NUMBER_REGEXP}(?:\s+(\S.*)$|\s*$)/.match(data)
|
825
|
+
unit = m[3] ? ::Stick::Units::Unit.new(m[3], self) : ::Stick::Units::Unit.new({}, self)
|
825
826
|
if m[1]
|
826
827
|
multiplier = m[2].empty? ? Integer(m[1]) : Float(m[1])
|
827
828
|
{:unit => unit, :multiplier => multiplier}
|
@@ -829,7 +830,7 @@ module Stick
|
|
829
830
|
{:unit => unit}
|
830
831
|
end
|
831
832
|
else
|
832
|
-
{:unit => ::Stick::Unit.new(data, self)}
|
833
|
+
{:unit => ::Stick::Units::Unit.new(data, self)}
|
833
834
|
end
|
834
835
|
end
|
835
836
|
|
@@ -850,16 +851,16 @@ module Stick
|
|
850
851
|
|
851
852
|
# Returns the current Converter in the current Thread.
|
852
853
|
# The default converter is the one returned by <code>converter(:default)</code>.
|
853
|
-
# See also Stick#with_converter and Converter.converter.
|
854
|
+
# See also Stick::Units#with_converter and Converter.converter.
|
854
855
|
def current
|
855
|
-
Thread.current[:'Stick::converter'] ||= converter(:default)
|
856
|
+
Thread.current[:'Stick::Units::converter'] ||= converter(:default)
|
856
857
|
end
|
857
858
|
|
858
859
|
def with_converter(conv) # :nodoc:
|
859
|
-
conv = converter(conv) if not conv.is_a? ::Stick::Converter
|
860
|
-
raise ::ArgumentError, "Converter expected" if not conv.is_a? ::Stick::Converter
|
860
|
+
conv = converter(conv) if not conv.is_a? ::Stick::Units::Converter
|
861
|
+
raise ::ArgumentError, "Converter expected" if not conv.is_a? ::Stick::Units::Converter
|
861
862
|
begin
|
862
|
-
old_conv = Thread.current[:'Stick::converter']
|
863
|
+
old_conv = Thread.current[:'Stick::Units::converter']
|
863
864
|
if old_conv
|
864
865
|
new_conv = Converter.send(:new, nil)
|
865
866
|
new_conv.include(old_conv)
|
@@ -867,10 +868,10 @@ module Stick
|
|
867
868
|
else
|
868
869
|
new_conv = conv
|
869
870
|
end
|
870
|
-
Thread.current[:'Stick::converter'] = new_conv
|
871
|
+
Thread.current[:'Stick::Units::converter'] = new_conv
|
871
872
|
yield
|
872
873
|
ensure
|
873
|
-
Thread.current[:'Stick::converter'] = old_conv
|
874
|
+
Thread.current[:'Stick::Units::converter'] = old_conv
|
874
875
|
end
|
875
876
|
end
|
876
877
|
|
@@ -918,7 +919,7 @@ module Stick
|
|
918
919
|
units.each_pair do |u, e|
|
919
920
|
(u.conversion != :none ? other_units : base_units)[u] = e
|
920
921
|
end
|
921
|
-
result = Conversion.new(::Stick::Unit.new(base_units, self), multiplier)
|
922
|
+
result = Conversion.new(::Stick::Units::Unit.new(base_units, self), multiplier)
|
922
923
|
other_units.each_pair do |u, e|
|
923
924
|
result *= (u.conversion ** e)
|
924
925
|
end
|
@@ -943,17 +944,17 @@ module Stick
|
|
943
944
|
end
|
944
945
|
|
945
946
|
end
|
946
|
-
|
947
|
+
end
|
947
948
|
|
948
949
|
class Numeric
|
949
950
|
#
|
950
951
|
def method_missing(m, *args, &blk)
|
951
952
|
if args.length == 1
|
952
|
-
args[0] = (::Stick::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Converter
|
953
|
-
return ::Stick::Value.new(self, ::Stick::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
|
954
|
-
elsif ::Stick::Converter.current.registered?(m)
|
953
|
+
args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
|
954
|
+
return ::Stick::Units::Value.new(self, ::Stick::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
|
955
|
+
elsif ::Stick::Units::Converter.current.registered?(m)
|
955
956
|
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
|
956
|
-
return ::Stick::Value.new(self, ::Stick::Unit.new({m => 1}, ::Stick::Converter.current))
|
957
|
+
return ::Stick::Units::Value.new(self, ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current))
|
957
958
|
end
|
958
959
|
::Exception.with_clean_backtrace("method_missing") {
|
959
960
|
super
|
@@ -962,7 +963,7 @@ class Numeric
|
|
962
963
|
|
963
964
|
#
|
964
965
|
def to_value(unit)
|
965
|
-
::Stick::Value.new(self, unit)
|
966
|
+
::Stick::Units::Value.new(self, unit)
|
966
967
|
end
|
967
968
|
end
|
968
969
|
|
@@ -970,11 +971,11 @@ end
|
|
970
971
|
class String
|
971
972
|
#
|
972
973
|
def to_unit(converter = nil)
|
973
|
-
::Stick::Unit.new(self, converter)
|
974
|
+
::Stick::Units::Unit.new(self, converter)
|
974
975
|
end
|
975
976
|
|
976
977
|
#
|
977
978
|
def to_value(converter = nil)
|
978
|
-
::Stick::Value.new(self, converter)
|
979
|
+
::Stick::Units::Value.new(self, converter)
|
979
980
|
end
|
980
981
|
end
|