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 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 Time object fails
110
- * 'string'.datetime returns a DateTime or a Time if the DateTime fails
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 functions
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 (:length, :mass, etc..)
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 * bug fix for compatibility with Rails
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.1
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.0'
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 scalar will first be converted to the target unit before output.
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 = self.zero? ? 1 : (self.scalar / self.base_scalar)
402
- Unit.new(:scalar=>(self.base_scalar + other.base_scalar)*q, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature)
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 = self.zero? ? 1 : (self.scalar / self.base_scalar)
420
- Unit.new(:scalar=>(self.base_scalar - other.base_scalar)*q, :numerator=>@numerator, :denominator=>@denominator, :signature=>@signature)
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 = "s")
1166
- other ? Unit.new("#{self.to_f} s").to(other) : Unit.new("#{self.to_f} s")
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
@@ -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.2
7
- date: 2006-10-03 00:00:00 -04:00
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