ruby-units 0.3.7 → 0.3.8

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.txt CHANGED
@@ -151,4 +151,7 @@ Change Log for Ruby-units
151
151
  * Improved handling for units with non-alphanumeric names
152
152
  (like ' for feet, # for pound)
153
153
  * Now you can enter durations as "HH:MM:SS, usec" or
154
- "HH:MM:SS:usec"
154
+ "HH:MM:SS:usec"
155
+
156
+ 2006-12-15 0.3.8 * Any object that supports a 'to_unit' method will now be
157
+ automatically coerced to a unit during math operations.
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.7
5
+ # = Ruby Units 0.3.8
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.7'
43
+ VERSION = '0.3.8'
44
44
  @@USER_DEFINITIONS = {}
45
45
  @@PREFIX_VALUES = {}
46
46
  @@PREFIX_MAP = {}
@@ -640,9 +640,7 @@ class Unit < Numeric
640
640
  alias :>> :to
641
641
  alias :convert_to :to
642
642
 
643
- # Eliminates terms in the passed numerator and denominator. Expands out prefixes and applies them to the
644
- # scalar. Returns a hash that can be used to initialize a new Unit object.
645
- # converts the unit back to a float if it is unitless
643
+ # converts the unit back to a float if it is unitless. Otherwise raises an exception
646
644
  def to_f
647
645
  return @scalar.to_f if self.unitless?
648
646
  raise RuntimeError, "Can't convert to float unless unitless. Use Unit#scalar"
@@ -708,13 +706,13 @@ class Unit < Numeric
708
706
  Unit.new(@scalar.floor, @numerator, @denominator)
709
707
  end
710
708
 
711
- # if unitless, returns an int
709
+ # if unitless, returns an int, otherwise raises an error
712
710
  def to_int
713
711
  return @scalar.to_int if self.unitless?
714
712
  raise RuntimeError, 'Cannot convert to Integer, use Unit#scalar'
715
713
  end
716
714
 
717
- # Tries to make a Time object from current unit
715
+ # Tries to make a Time object from current unit. Assumes the current unit hold the duration in seconds from the epoch.
718
716
  def to_time
719
717
  Time.at(self)
720
718
  end
@@ -726,6 +724,8 @@ class Unit < Numeric
726
724
  Unit.new(@scalar.truncate, @numerator, @denominator)
727
725
  end
728
726
 
727
+ # convert a duration to a DateTime. This will work so long as the duration is the duration from the zero date
728
+ # defined by DateTime
729
729
  def to_datetime
730
730
  DateTime.new(self.to('d').scalar)
731
731
  end
@@ -792,14 +792,21 @@ class Unit < Numeric
792
792
  end
793
793
  alias :after :from
794
794
  alias :from_now :from
795
-
795
+
796
+ # returns next unit in a range. '1 mm'.unit.succ #=> '2 mm'.unit
797
+ # only works when the scalar is an integer
796
798
  def succ
797
799
  raise ArgumentError, "Non Integer Scalar" unless @scalar == @scalar.to_i
798
800
  q = @scalar.to_i.succ
799
801
  Unit.new(q, @numerator, @denominator)
800
802
  end
801
803
 
804
+ # automatically coerce objects to units when possible
805
+ # if an object defines a 'to_unit' method, it will be coerced using that method
802
806
  def coerce(other)
807
+ if other.respond_to? :to_unit
808
+ return [other.to_unit, self]
809
+ end
803
810
  case other
804
811
  when Unit : [other, self]
805
812
  else
@@ -1017,7 +1024,7 @@ class Unit < Numeric
1017
1024
  @denominator = bottom.scan(@@UNIT_MATCH_REGEX).delete_if {|x| x.empty?}.compact if bottom
1018
1025
  us = "#{(top || '' + bottom || '')}".to_s.gsub(@@UNIT_MATCH_REGEX,'').gsub(/[\d\*, "'_^\/\$]/,'')
1019
1026
 
1020
- raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized ('#{us}' left '#{top =~ @@UNIT_MATCH_REGEX}')") unless us.empty?
1027
+ raise( ArgumentError, "'#{passed_unit_string}' Unit not recognized") unless us.empty?
1021
1028
 
1022
1029
  @numerator = @numerator.map do |item|
1023
1030
  @@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
@@ -43,6 +43,12 @@ class DateTime
43
43
  end
44
44
  end
45
45
 
46
+ class Dummy
47
+ def to_unit
48
+ '1 mm'.unit
49
+ end
50
+ end
51
+
46
52
  class TestRubyUnits < Test::Unit::TestCase
47
53
 
48
54
  def setup
@@ -835,4 +841,10 @@ class TestRubyUnits < Test::Unit::TestCase
835
841
  assert_equal "1:30:30".unit, "1.5 hour".unit + '30 sec'.unit
836
842
  assert_equal "1:30:30,200".unit, "1.5 hour".unit + '30 sec'.unit + '200 usec'.unit
837
843
  end
844
+
845
+ def test_coercion
846
+ a = Dummy.new
847
+ b = '1 mm'.unit
848
+ assert_equal '2 mm'.unit, b + a
849
+ end
838
850
  end
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
7
- date: 2006-12-14 00:00:00 -05:00
6
+ version: 0.3.8
7
+ date: 2006-12-15 00:00:00 -05:00
8
8
  summary: A model that performs unit conversions and unit math
9
9
  require_paths:
10
10
  - lib