ruby-units 0.3.2 → 0.3.3
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/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
|