ruby-units 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +16 -6
- data/lib/ruby-units.rb +36 -15
- data/test/test_ruby-units.rb +42 -0
- metadata +2 -2
data/CHANGELOG
CHANGED
@@ -106,17 +106,27 @@ Change Log for Ruby-units
|
|
106
106
|
* better test coverage
|
107
107
|
* The 'string'.to_time returns a Time object
|
108
108
|
* 'string'.to_datetime returns a DateTime object
|
109
|
-
* 'string'.time returns a Time object or a DateTime if the
|
110
|
-
|
109
|
+
* 'string'.time returns a Time object or a DateTime if the
|
110
|
+
Time object fails
|
111
|
+
* 'string'.datetime returns a DateTime or a Time if the
|
112
|
+
DateTime fails
|
111
113
|
|
112
|
-
2006-10-02 0.3.0 * Performance enhanced by caching results of many
|
113
|
-
(Thanks to Kurt Stephens for pushing this.)
|
114
|
+
2006-10-02 0.3.0 * Performance enhanced by caching results of many
|
115
|
+
functions (Thanks to Kurt Stephens for pushing this.)
|
114
116
|
* Throws an exception if the unit is not recognized
|
115
|
-
* units can now identify what 'kind' they are
|
117
|
+
* units can now identify what 'kind' they are
|
118
|
+
(:length, :mass, etc..)
|
116
119
|
* New constructors:
|
117
120
|
Unit(1,"mm")
|
118
121
|
Unit(1,"mm/s")
|
119
122
|
Unit(1,"mm","s")
|
123
|
+
|
120
124
|
2006-10-02 0.3.1 * minor bug fixes
|
121
125
|
|
122
|
-
2006-10-03 0.3.2 *
|
126
|
+
2006-10-03 0.3.2 * More minor bug fixes
|
127
|
+
(now fixes a minor name collision with rails)
|
128
|
+
|
129
|
+
2006-10-03 0.3.3 * Apparently I can't do math late at night.
|
130
|
+
Fixed a bug that would cause problems when adding
|
131
|
+
or subtracting units to a unit with a zero scalar.
|
132
|
+
* Date and DateTime objects can be converted to 'units'
|
data/lib/ruby-units.rb
CHANGED
@@ -2,7 +2,7 @@ require 'mathn'
|
|
2
2
|
require 'rational'
|
3
3
|
require 'date'
|
4
4
|
require 'parsedate'
|
5
|
-
# = Ruby Units 0.3.
|
5
|
+
# = Ruby Units 0.3.3
|
6
6
|
#
|
7
7
|
# Copyright 2006 by Kevin C. Olbrich, Ph.D.
|
8
8
|
#
|
@@ -40,7 +40,7 @@ require 'parsedate'
|
|
40
40
|
class Unit < Numeric
|
41
41
|
require 'units'
|
42
42
|
# pre-generate hashes from unit definitions for performance.
|
43
|
-
VERSION = '0.3.
|
43
|
+
VERSION = '0.3.3'
|
44
44
|
@@USER_DEFINITIONS = {}
|
45
45
|
@@PREFIX_VALUES = {}
|
46
46
|
@@PREFIX_MAP = {}
|
@@ -129,8 +129,7 @@ class Unit < Numeric
|
|
129
129
|
end
|
130
130
|
@@PREFIX_REGEX = @@PREFIX_MAP.keys.sort_by {|prefix| prefix.length}.reverse.join('|')
|
131
131
|
@@UNIT_REGEX = @@UNIT_MAP.keys.sort_by {|unit| unit.length}.reverse.join('|')
|
132
|
-
@@UNIT_MATCH_REGEX = /(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/
|
133
|
-
|
132
|
+
@@UNIT_MATCH_REGEX = /(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/
|
134
133
|
end
|
135
134
|
|
136
135
|
|
@@ -214,6 +213,10 @@ class Unit < Numeric
|
|
214
213
|
@scalar = options[0].to_f
|
215
214
|
@numerator = ['<second>']
|
216
215
|
@denominator = UNITY_ARRAY
|
216
|
+
when DateTime:
|
217
|
+
@scalar = options[0].ajd
|
218
|
+
@numerator = ['<day>']
|
219
|
+
@denominator = UNITY_ARRAY
|
217
220
|
else
|
218
221
|
raise ArgumentError, "Invalid Unit Format"
|
219
222
|
end
|
@@ -265,7 +268,8 @@ class Unit < Numeric
|
|
265
268
|
return @is_base = true
|
266
269
|
end
|
267
270
|
|
268
|
-
#convert to base SI units
|
271
|
+
# convert to base SI units
|
272
|
+
# results of the conversion are cached so subsequent calls to this will be fast
|
269
273
|
def to_base
|
270
274
|
return self if self.is_base?
|
271
275
|
cached = @@base_unit_cache[self.units] * self.scalar rescue nil
|
@@ -302,11 +306,17 @@ class Unit < Numeric
|
|
302
306
|
end
|
303
307
|
|
304
308
|
# Generate human readable output.
|
305
|
-
# If the name of a unit is passed, the
|
309
|
+
# If the name of a unit is passed, the unit will first be converted to the target unit before output.
|
306
310
|
# some named conversions are available
|
307
311
|
#
|
308
312
|
# :ft - outputs in feet and inches (e.g., 6'4")
|
309
313
|
# :lbs - outputs in pounds and ounces (e.g, 8 lbs, 8 oz)
|
314
|
+
#
|
315
|
+
# You can also pass a standard format string (i.e., '%0.2f')
|
316
|
+
# or a strftime format string.
|
317
|
+
#
|
318
|
+
# output is cached so subsequent calls for the same format will be fast
|
319
|
+
#
|
310
320
|
def to_s(target_units=nil)
|
311
321
|
out = @output[target_units] rescue nil
|
312
322
|
if out
|
@@ -334,6 +344,7 @@ class Unit < Numeric
|
|
334
344
|
end
|
335
345
|
end
|
336
346
|
|
347
|
+
# Normally pretty prints the unit, but if you really want to see the guts of it, pass ':dump'
|
337
348
|
def inspect(option=nil)
|
338
349
|
return super() if option == :dump
|
339
350
|
self.to_s
|
@@ -395,11 +406,12 @@ class Unit < Numeric
|
|
395
406
|
|
396
407
|
# Add two units together. Result is same units as receiver and scalar and base_scalar are updated appropriately
|
397
408
|
# throws an exception if the units are not compatible.
|
409
|
+
# It is possible to add Time objects to units of time
|
398
410
|
def +(other)
|
399
411
|
if Unit === other
|
400
412
|
if self =~ other then
|
401
|
-
q
|
402
|
-
Unit.new(:scalar=>(self.base_scalar + other.base_scalar)
|
413
|
+
@q ||= @@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar
|
414
|
+
Unit.new(:scalar=>(self.base_scalar + other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature)
|
403
415
|
else
|
404
416
|
raise ArgumentError, "Incompatible Units"
|
405
417
|
end
|
@@ -416,8 +428,8 @@ class Unit < Numeric
|
|
416
428
|
def -(other)
|
417
429
|
if Unit === other
|
418
430
|
if self =~ other then
|
419
|
-
q
|
420
|
-
Unit.new(:scalar=>(self.base_scalar - other.base_scalar)
|
431
|
+
@q ||= @@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar
|
432
|
+
Unit.new(:scalar=>(self.base_scalar - other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature=>@signature)
|
421
433
|
else
|
422
434
|
raise ArgumentError, "Incompatible Units"
|
423
435
|
end
|
@@ -699,6 +711,10 @@ class Unit < Numeric
|
|
699
711
|
alias :time :to_time
|
700
712
|
alias :to_i :to_int
|
701
713
|
alias :truncate :to_int
|
714
|
+
|
715
|
+
def to_datetime
|
716
|
+
DateTime.new(self.to('d').scalar)
|
717
|
+
end
|
702
718
|
|
703
719
|
def round
|
704
720
|
Unit.new(@scalar.round, @numerator, @denominator)
|
@@ -988,7 +1004,7 @@ end
|
|
988
1004
|
# Date.today + U"1 week" => gives today+1 week
|
989
1005
|
class Date
|
990
1006
|
alias :unit_date_add :+
|
991
|
-
def +unit
|
1007
|
+
def +(unit)
|
992
1008
|
case unit
|
993
1009
|
when Unit:
|
994
1010
|
unit = unit.to('d').round if ['y', 'decade', 'century'].include? unit.units
|
@@ -1000,7 +1016,7 @@ class Date
|
|
1000
1016
|
end
|
1001
1017
|
|
1002
1018
|
alias :unit_date_sub :-
|
1003
|
-
def -unit
|
1019
|
+
def -(unit)
|
1004
1020
|
case unit
|
1005
1021
|
when Unit:
|
1006
1022
|
unit = unit.to('d').round if ['y', 'decade', 'century'].include? unit.units
|
@@ -1011,6 +1027,11 @@ class Date
|
|
1011
1027
|
end
|
1012
1028
|
end
|
1013
1029
|
|
1030
|
+
def to_unit(other = nil)
|
1031
|
+
other ? Unit.new(self).to(other) : Unit.new(self)
|
1032
|
+
end
|
1033
|
+
alias :unit :to_unit
|
1034
|
+
|
1014
1035
|
def to_time
|
1015
1036
|
Time.local(*ParseDate.parsedate(self.to_s))
|
1016
1037
|
end
|
@@ -1072,7 +1093,6 @@ class String
|
|
1072
1093
|
|
1073
1094
|
#needed for compatibility with Rails, which defines a String.from method
|
1074
1095
|
if self.public_instance_methods.include? 'from'
|
1075
|
-
puts 'rails'
|
1076
1096
|
alias :old_from :from
|
1077
1097
|
end
|
1078
1098
|
|
@@ -1162,8 +1182,8 @@ class Time
|
|
1162
1182
|
end
|
1163
1183
|
end
|
1164
1184
|
|
1165
|
-
def to_unit(other =
|
1166
|
-
other ? Unit.new(
|
1185
|
+
def to_unit(other = nil)
|
1186
|
+
other ? Unit.new(self).to(other) : Unit.new(self)
|
1167
1187
|
end
|
1168
1188
|
alias :unit :to_unit
|
1169
1189
|
alias :u :to_unit
|
@@ -1186,6 +1206,7 @@ class Time
|
|
1186
1206
|
end
|
1187
1207
|
end
|
1188
1208
|
|
1209
|
+
# usage: Time.in '5 min'
|
1189
1210
|
def self.in(duration)
|
1190
1211
|
Time.now + duration.to_unit
|
1191
1212
|
end
|
data/test/test_ruby-units.rb
CHANGED
@@ -248,6 +248,40 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
248
248
|
}
|
249
249
|
end
|
250
250
|
|
251
|
+
def test_add_operator
|
252
|
+
a = '0 mm'.unit
|
253
|
+
b = '10 cm'.unit
|
254
|
+
c = '1 in'.unit
|
255
|
+
d = '1 ml'.unit
|
256
|
+
|
257
|
+
assert_equal (a+b).scalar, 100
|
258
|
+
assert_equal (a+b).units, 'mm'
|
259
|
+
assert_equal (b+a).scalar, 10
|
260
|
+
assert_equal (b+a).units, 'cm'
|
261
|
+
assert_in_delta 0.01, (b+c).scalar, 12.54
|
262
|
+
assert_equal (b+c).units, 'cm'
|
263
|
+
assert_raises(ArgumentError) {
|
264
|
+
a + d
|
265
|
+
}
|
266
|
+
end
|
267
|
+
|
268
|
+
def test_subtract_operator
|
269
|
+
a = '0 mm'.unit
|
270
|
+
b = '10 cm'.unit
|
271
|
+
c = '1 in'.unit
|
272
|
+
d = '1 ml'.unit
|
273
|
+
|
274
|
+
assert_equal (a-b).scalar, -100
|
275
|
+
assert_equal (a-b).units, 'mm'
|
276
|
+
assert_equal (b-a).scalar, 10
|
277
|
+
assert_equal (b-a).units, 'cm'
|
278
|
+
assert_in_delta 0.01, (b-c).scalar, 7.46
|
279
|
+
assert_equal (b-c).units, 'cm'
|
280
|
+
assert_raises(ArgumentError) {
|
281
|
+
a - d
|
282
|
+
}
|
283
|
+
end
|
284
|
+
|
251
285
|
def test_convert_to
|
252
286
|
unit1 = Unit.new("1 mm")
|
253
287
|
unit2 = Unit.new("1 ft")
|
@@ -404,6 +438,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
404
438
|
unit3 = unit1 * unit2
|
405
439
|
assert_equal Unit.new("1 m^2/ms^2"), unit3
|
406
440
|
}
|
441
|
+
assert_equal unit1 * 0, '0 m/ms'.unit
|
407
442
|
end
|
408
443
|
|
409
444
|
def test_divide
|
@@ -413,6 +448,12 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
413
448
|
unit3 = unit1 / unit2
|
414
449
|
assert_equal Unit.new("1 M"), unit3
|
415
450
|
}
|
451
|
+
assert_equal unit2 / 1, unit2
|
452
|
+
unit3 = '0 s'.unit
|
453
|
+
assert_raises(ZeroDivisionError) {
|
454
|
+
unit1 / unit3
|
455
|
+
}
|
456
|
+
|
416
457
|
assert_raises(ZeroDivisionError) {
|
417
458
|
unit1 / 0
|
418
459
|
}
|
@@ -422,6 +463,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
422
463
|
unit1 = Unit.new("1 m")
|
423
464
|
unit2 = Unit.new("1 1/m")
|
424
465
|
assert_equal unit2, unit1.inverse
|
466
|
+
assert_raises (ZeroDivisionError) { 0.unit.inverse }
|
425
467
|
end
|
426
468
|
|
427
469
|
def test_exponentiate_positive
|
metadata
CHANGED
@@ -3,8 +3,8 @@ rubygems_version: 0.9.0
|
|
3
3
|
specification_version: 1
|
4
4
|
name: ruby-units
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.3.
|
7
|
-
date: 2006-10-
|
6
|
+
version: 0.3.3
|
7
|
+
date: 2006-10-05 00:00:00 -04:00
|
8
8
|
summary: A model that performs unit conversions and unit math
|
9
9
|
require_paths:
|
10
10
|
- lib
|