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 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