ruby-units 0.3.7 → 0.3.8

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