ruby-units 1.0.2 → 1.1.0

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.
@@ -1,5 +1,9 @@
1
1
  Change Log for Ruby-units
2
2
  =========================
3
+ 2007-01-28 1.1.0 * completely revamped the temperature handling system (see README)
4
+ * fixed some spelling errors in some units
5
+ * fixed to_datetime and to_date to convert durations to datetimes and dates'
6
+
3
7
  2007-01-24 1.0.2 * Minor changes in the way powers are calculated to support Uncertain
4
8
  numbers better.
5
9
  * Fixed parsing bug with Uncertain Numbers
data/README.txt CHANGED
@@ -1,7 +1,5 @@
1
1
  =Ruby Units
2
2
 
3
- Version: 1.0.1
4
-
5
3
  Kevin C. Olbrich, Ph.D.
6
4
  kevin.olbrich@gmail.com
7
5
 
@@ -139,3 +137,37 @@ works so long as the starting point has an integer scalar
139
137
  All Trig math functions (sin, cos, sinh, hypot...) can take a unit as their parameter.
140
138
  It will be converted to radians and then used if possible.
141
139
 
140
+ ==Temperatures
141
+ Ruby-units makes a distinction between a temperature (which technically is a property) and
142
+ degrees of temperature (which temperatures are measured in).
143
+
144
+ Temperature units (i.e., 'tempK') can be converted back and forth, and will take into account
145
+ the differences in the zero points of the various scales. Differential temperature (e.g., '100 degC'.unit)
146
+ units behave like most other units.
147
+
148
+ '37 tempC'.unit >> 'tempF' #=> 98.6 tempF
149
+
150
+ Ruby-units will raise an exception if you attempt to create a temperature unit that would
151
+ fall below absolute zero.
152
+
153
+ Unit math on temperatures is fairly limited.
154
+
155
+ '100 tempC'.unit + '10 degC'.unit #=> '110 tempC'.unit
156
+ '100 tempC'.unit - '10 degC'.unit #=> '90 tempC'.unit
157
+ '100 tempC'.unit + '50 tempC'.unit #=> exception
158
+ '100 tempC'.unit - '50 tempC'.unit #=> '50 degC'.unit
159
+ '50 tempC'.unit - '100 tempC'.unit #=> '-50 degC'.unit
160
+ '100 tempC'.unit * [scalar] #=> '100*scalar tempC'.unit
161
+ '100 tempC'.unit / [scalar] #=> '100/scalar tempC'.unit
162
+ '100 tempC'.unit * [unit] #=> exception
163
+ '100 tempC'.unit / [unit] #=> exception
164
+ '100 tempC'.unit ** N #=> exception
165
+
166
+ '100 tempC'.unit >> 'degC' #=> '100 degC'.unit
167
+ This conversion references the 0 point on the scale of the temperature unit
168
+
169
+ '100 degC'.unit >> 'tempC' #=> '-173 tempC'.unit
170
+ These conversions are always interpreted as being relative to absolute zero.
171
+ Conversions are probably better done like this...
172
+ '0 tempC'.unit + '100 degC'.unit #=> '100 tempC'.unit
173
+
@@ -3,18 +3,6 @@ require 'rational'
3
3
  require 'date'
4
4
  require 'parsedate'
5
5
 
6
-
7
- =begin
8
- require 'math'
9
-
10
- require 'object_class'
11
- require 'array_class'
12
- require 'string_class'
13
- require 'date_class'
14
- require 'time_class'
15
- require 'numeric_class'
16
- =end
17
-
18
6
  # = Ruby Units
19
7
  #
20
8
  # Copyright 2006 by Kevin C. Olbrich, Ph.D.
@@ -52,14 +40,14 @@ require 'numeric_class'
52
40
  # Unit.setup
53
41
  class Unit < Numeric
54
42
  # pre-generate hashes from unit definitions for performance.
55
- VERSION = '1.0.2'
43
+ VERSION = '1.1.0'
56
44
  @@USER_DEFINITIONS = {}
57
45
  @@PREFIX_VALUES = {}
58
46
  @@PREFIX_MAP = {}
59
47
  @@UNIT_MAP = {}
60
48
  @@UNIT_VALUES = {}
61
49
  @@OUTPUT_MAP = {}
62
- @@BASE_UNITS = ['<meter>','<kilogram>','<second>','<mole>', '<farad>', '<ampere>','<radian>','<kelvin>','<byte>','<dollar>','<candela>','<each>','<steradian>','<decibel>']
50
+ @@BASE_UNITS = ['<meter>','<kilogram>','<second>','<mole>', '<farad>', '<ampere>','<radian>','<kelvin>','<temp-K>','<byte>','<dollar>','<candela>','<each>','<steradian>','<decibel>']
63
51
  UNITY = '<1>'
64
52
  UNITY_ARRAY= [UNITY]
65
53
  FEET_INCH_REGEX = /(\d+)\s*(?:'|ft|feet)\s*(\d+)\s*(?:"|in|inches)/
@@ -76,9 +64,9 @@ class Unit < Numeric
76
64
  COMPLEX_REGEX = /#{COMPLEX_NUMBER}\s?(.+)?/
77
65
  RATIONAL_REGEX = /#{RATIONAL_NUMBER}\s?(.+)?/
78
66
  KELVIN = ['<kelvin>']
79
- FARENHEIT = ['<farenheit>']
67
+ FAHRENHEIT = ['<fahrenheit>']
80
68
  RANKINE = ['<rankine>']
81
- CELCIUS = ['<celcius>']
69
+ CELSIUS = ['<celsius>']
82
70
 
83
71
  SIGNATURE_VECTOR = [:length, :time, :temperature, :mass, :current, :substance, :luminosity, :currency, :memory, :angle, :capacitance]
84
72
  @@KINDS = {
@@ -224,7 +212,6 @@ class Unit < Numeric
224
212
  return
225
213
  end
226
214
 
227
-
228
215
  case options[0]
229
216
  when Hash:
230
217
  @scalar = options[0][:scalar] || 1
@@ -251,7 +238,8 @@ class Unit < Numeric
251
238
  raise ArgumentError, "Invalid Unit Format"
252
239
  end
253
240
  self.update_base_scalar
254
- self.replace_temperature
241
+ raise ArgumentError, "Temperature out of range" if self.is_temperature? && self.base_scalar < 0
242
+
255
243
 
256
244
  unary_unit = self.units || ""
257
245
  opt_units = options[0].scan(NUMBER_REGEX)[0][1] if String === options[0]
@@ -290,7 +278,7 @@ class Unit < Numeric
290
278
  # Returns 'true' if the Unit is represented in base units
291
279
  def is_base?
292
280
  return @is_base if defined? @is_base
293
- return @is_base=true if @signature == 400 && @numerator.size == 1 && @numerator[0] =~ /(celcius|kelvin|farenheit|rankine)/
281
+ return @is_base=true if @signature == 400 && self.numerator.size == 1 && self.denominator == UNITY_ARRAY && self.units =~ /(deg|temp)K/
294
282
  n = @numerator + @denominator
295
283
  for x in n.compact do
296
284
  return @is_base=false unless x == UNITY || (@@BASE_UNITS.include?((x)))
@@ -302,9 +290,18 @@ class Unit < Numeric
302
290
  # results of the conversion are cached so subsequent calls to this will be fast
303
291
  def to_base
304
292
  return self if self.is_base?
305
- cached = @@base_unit_cache[self.units] * self.scalar rescue nil
293
+ if self.units =~ /\A(deg|temp)(C|F|K|C)\Z/
294
+ @signature = 400
295
+ base = case self.units
296
+ when /temp/ : self.to('tempK')
297
+ when /deg/ : self.to('degK')
298
+ end
299
+ return base
300
+ end
301
+
302
+ cached = ((@@base_unit_cache[self.units] * self.scalar) rescue nil)
306
303
  return cached if cached
307
-
304
+
308
305
  num = []
309
306
  den = []
310
307
  q = 1
@@ -385,6 +382,16 @@ class Unit < Numeric
385
382
  self.to_s
386
383
  end
387
384
 
385
+ def is_temperature?
386
+ return true if self.signature == 400 && self.units =~ /temp/
387
+ end
388
+
389
+ def temperature_scale
390
+ return nil unless self.is_temperature?
391
+ self.units =~ /temp(C|F|R|K)/
392
+ "deg#{$1}"
393
+ end
394
+
388
395
  # returns true if no associated units
389
396
  # false, even if the units are "unitless" like 'radians, each, etc'
390
397
  def unitless?
@@ -449,8 +456,18 @@ class Unit < Numeric
449
456
  case
450
457
  when self.zero? : other.dup
451
458
  when self =~ other :
452
- @q ||= @@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar
453
- Unit.new(:scalar=>(self.base_scalar + other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature)
459
+ raise ArgumentError, "Cannot add two temperatures" if (self.is_temperature? && other.is_temperature?)
460
+ if [self, other].any? {|x| x.is_temperature?}
461
+ case self.is_temperature?
462
+ when true:
463
+ Unit.new(:scalar => (self.scalar + other.to(self.temperature_scale).scalar), :numerator => @numerator, :denominator=>@denominator, :signature => @signature)
464
+ else
465
+ Unit.new(:scalar => (other.scalar + self.to(other.temperature_scale).scalar), :numerator => other.numerator, :denominator=>other.denominator, :signature => other.signature)
466
+ end
467
+ else
468
+ @q ||= ((@@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar) rescue (self.units.unit.to_base.scalar))
469
+ Unit.new(:scalar=>(self.base_scalar + other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature => @signature)
470
+ end
454
471
  else
455
472
  raise ArgumentError, "Incompatible Units ('#{self}' not compatible with '#{other}')"
456
473
  end
@@ -469,8 +486,17 @@ class Unit < Numeric
469
486
  case
470
487
  when self.zero? : -other.dup
471
488
  when self =~ other :
472
- @q ||= @@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar
473
- Unit.new(:scalar=>(self.base_scalar - other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature=>@signature)
489
+ case
490
+ when [self, other].all? {|x| x.is_temperature?} :
491
+ Unit.new(:scalar => (self.base_scalar - other.base_scalar), :numerator => KELVIN, :denominator => UNITY_ARRAY, :signature => @signature).to(self.temperature_scale)
492
+ when self.is_temperature? :
493
+ Unit.new(:scalar => (self.base_scalar - other.base_scalar), :numerator => ['<temp-K>'], :denominator => UNITY_ARRAY, :signature => @signature).to(self)
494
+ when other.is_temperature? :
495
+ raise ArgumentError, "Cannot subtract a temperature from a differential unit"
496
+ else
497
+ @q ||= ((@@cached_units[self.units].scalar / @@cached_units[self.units].base_scalar) rescue (self.units.unit.scalar/self.units.unit.to_base.scalar))
498
+ Unit.new(:scalar=>(self.base_scalar - other.base_scalar)*@q, :numerator=>@numerator, :denominator=>@denominator, :signature=>@signature)
499
+ end
474
500
  else
475
501
  raise ArgumentError, "Incompatible Units ('#{self}' not compatible with '#{other}')"
476
502
  end
@@ -486,6 +512,7 @@ class Unit < Numeric
486
512
  def *(other)
487
513
  case other
488
514
  when Unit
515
+ raise ArgumentError, "Cannot multiply by temperatures" if [other,self].any? {|x| x.is_temperature?}
489
516
  opts = Unit.eliminate_terms(@scalar*other.scalar, @numerator + other.numerator ,@denominator + other.denominator)
490
517
  opts.merge!(:signature => @signature + other.signature)
491
518
  Unit.new(opts)
@@ -503,6 +530,7 @@ class Unit < Numeric
503
530
  case other
504
531
  when Unit
505
532
  raise ZeroDivisionError if other.zero?
533
+ raise ArgumentError, "Cannot divide with temperatures" if [other,self].any? {|x| x.is_temperature?}
506
534
  opts = Unit.eliminate_terms(@scalar/other.scalar, @numerator + other.denominator ,@denominator + other.numerator)
507
535
  opts.merge!(:signature=> @signature - other.signature)
508
536
  Unit.new(opts)
@@ -524,6 +552,7 @@ class Unit < Numeric
524
552
  #
525
553
  # For now, if a rational is passed in, it will be used, otherwise we are stuck with integers and certain floats < 1
526
554
  def **(other)
555
+ raise ArgumentError, "Cannot exponentiate a temperature" if self.is_temperature?
527
556
  if Numeric === other
528
557
  return Unit("1") if other.zero?
529
558
  return self if other == 1
@@ -546,6 +575,7 @@ class Unit < Numeric
546
575
 
547
576
  # returns the unit raised to the n-th power. Integers only
548
577
  def power(n)
578
+ raise ArgumentError, "Cannot raise a temperature to a power" if self.is_temperature?
549
579
  raise ArgumentError, "Can only use Integer exponenents" unless Integer === n
550
580
  return self if n == 1
551
581
  return Unit("1") if n == 0
@@ -560,6 +590,7 @@ class Unit < Numeric
560
590
  # Calculates the n-th root of a unit, where n = (1..9)
561
591
  # if n < 0, returns 1/unit^(1/n)
562
592
  def root(n)
593
+ raise ArgumentError, "Cannot take the root of a temperature" if self.is_temperature?
563
594
  raise ArgumentError, "Exponent must an Integer" unless Integer === n
564
595
  raise ArgumentError, "0th root undefined" if n == 0
565
596
  return self if n == 1
@@ -602,7 +633,7 @@ class Unit < Numeric
602
633
  #
603
634
  # Special handling for temperature conversions is supported. If the Unit object is converted
604
635
  # from one temperature unit to another, the proper temperature offsets will be used.
605
- # Supports Kelvin, Celcius, Farenheit, and Rankine scales.
636
+ # Supports Kelvin, Celcius, fahrenheit, and Rankine scales.
606
637
  #
607
638
  # Note that if temperature is part of a compound unit, the temperature will be treated as a differential
608
639
  # and the units will be scaled appropriately.
@@ -610,45 +641,63 @@ class Unit < Numeric
610
641
  return self if other.nil?
611
642
  return self if TrueClass === other
612
643
  return self if FalseClass === other
613
- if (Unit === other && other.units =~ /temp(K|C|R|F)/) || (String === other && other =~ /temp(K|C|R|F)/)
614
- raise ArgumentError, "Receiver is not a temperature unit" unless self.signature==400
644
+ if (Unit === other && other.is_temperature?) || (String === other && other =~ /temp(K|C|R|F)/)
645
+ raise ArgumentError, "Receiver is not a temperature unit" unless self.signature == 400
615
646
  start_unit = self.units
616
647
  target_unit = other.units rescue other
648
+ unless @base_scalar
649
+ @base_scalar = case start_unit
650
+ when 'tempC' : @scalar + 273.15
651
+ when 'tempK' : @scalar
652
+ when 'tempF' : (@scalar+459.67)*(5.0/9.0)
653
+ when 'tempR' : @scalar*(5.0/9.0)
654
+ end
655
+ end
656
+ q= case target_unit
657
+ when 'tempC' : @base_scalar - 273.15
658
+ when 'tempK' : @base_scalar
659
+ when 'tempF' : @base_scalar * (9.0/5.0) - 459.67
660
+ when 'tempR' : @base_scalar * (9.0/5.0)
661
+ end
662
+
663
+ =begin
617
664
  q=case start_unit
618
- when 'degC':
665
+ when /\A(temp|deg)C\Z/:
619
666
  case target_unit
620
667
  when 'tempC' : @scalar
621
668
  when 'tempK' : @scalar + 273.15
622
669
  when 'tempF' : @scalar * (9.0/5.0) + 32.0
623
670
  when 'tempR' : @scalar * (9.0/5.0) + 491.67
624
671
  end
625
- when 'degK':
672
+ when /\A(temp|deg)K\Z/:
626
673
  case target_unit
627
674
  when 'tempC' : @scalar - 273.15
628
675
  when 'tempK' : @scalar
629
676
  when 'tempF' : @scalar * (9.0/5.0) - 459.67
630
677
  when 'tempR' : @scalar * (9.0/5.0)
631
678
  end
632
- when 'degF':
679
+ when /\A(temp|deg)F\Z/:
633
680
  case target_unit
634
681
  when 'tempC' : (@scalar-32)*(5.0/9.0)
635
682
  when 'tempK' : (@scalar+459.67)*(5.0/9.0)
636
683
  when 'tempF' : @scalar
637
684
  when 'tempR' : @scalar + 459.67
638
685
  end
639
- when 'degR':
686
+ when /\A(temp|deg)R\Z/:
640
687
  case target_unit
641
688
  when 'tempC' : @scalar*(5.0/9.0) -273.15
642
689
  when 'tempK' : @scalar*(5.0/9.0)
643
690
  when 'tempF' : @scalar - 459.67
644
691
  when 'tempR' : @scalar
645
692
  end
693
+
646
694
  else
647
695
  return self.to_base.to(other) unless self.is_base?
648
696
  #raise ArgumentError, "Unknown temperature conversion requested #{self.numerator}"
649
697
  end
650
- target_unit =~ /temp(C|K|F|R)/
651
- Unit.new("#{q} deg#{$1}")
698
+ =end
699
+ #target_unit =~ /temp(C|K|F|R)/
700
+ Unit.new("#{q} #{target_unit}")
652
701
  else
653
702
  case other
654
703
  when Unit:
@@ -726,9 +775,9 @@ class Unit < Numeric
726
775
 
727
776
  # negates the scalar of the Unit
728
777
  def -@
778
+ #raise ArgumentError, "Cannot negate an absolute temperature" if self.is_temperature? && ['degK','degR'].include?(self.temperature_scale)
729
779
  return -@scalar if self.unitless?
730
- #Unit.new(-@scalar,@numerator,@denominator)
731
- -1 * self.dup
780
+ self.dup * -1
732
781
  end
733
782
 
734
783
  # returns abs of scalar, without the units
@@ -767,7 +816,11 @@ class Unit < Numeric
767
816
  # convert a duration to a DateTime. This will work so long as the duration is the duration from the zero date
768
817
  # defined by DateTime
769
818
  def to_datetime
770
- DateTime.new(self.to('d').scalar)
819
+ DateTime.new0(self.to('d').scalar)
820
+ end
821
+
822
+ def to_date
823
+ Date.new0(self.to('d').scalar)
771
824
  end
772
825
 
773
826
  def round
@@ -892,20 +945,6 @@ class Unit < Numeric
892
945
  end
893
946
  vector
894
947
  end
895
-
896
- def replace_temperature
897
- return self unless self.kind == :temperature && self.units =~ /temp(R|K|F|C)/
898
- un = $1
899
- @numerator = case un
900
- when 'R' : RANKINE
901
- when 'C' : CELCIUS
902
- when 'F' : FARENHEIT
903
- when 'K' : KELVIN
904
- end
905
- @unit_name = nil
906
- r= self.to("tempK")
907
- copy(r)
908
- end
909
948
 
910
949
  private
911
950
 
@@ -39,7 +39,7 @@ UNIT_DEFINITIONS = {
39
39
  '<inch>' => [%w{in inch inches "}, 0.0254, :length, %w{<meter>}],
40
40
  '<foot>' => [%w{ft foot feet '}, 0.3048, :length, %w{<meter>}],
41
41
  '<yard>' => [%w{yd yard yards}, 0.9144, :length, %w{<meter>}],
42
- '<mile>' => [%w{mi mile miles "}, 1609.344, :length, %w{<meter>}],
42
+ '<mile>' => [%w{mi mile miles}, 1609.344, :length, %w{<meter>}],
43
43
  '<naut-mile>' => [%w{nmi}, 1852, :length, %w{<meter>}],
44
44
  '<league>'=> [%w{league leagues}, 4828, :length, %w{<meter>}],
45
45
  '<furlong>'=> [%w{furlong furlongs}, 201.2, :length, %w{<meter>}],
@@ -93,14 +93,14 @@ UNIT_DEFINITIONS = {
93
93
  '<gee>' => [%w{gee}, 9.80655, :acceleration, %w{<meter>}, %w{<second> <second>}],
94
94
 
95
95
  #temperature_difference
96
- '<kelvin>' => [%w{degK kelvin Kelvin}, 1.0, :temperature, %w{<kelvin>}],
97
- '<celcius>' => [%w{degC celcius Celcius}, 1.0, :temperature, %w{<kelvin>}],
98
- '<farenheit>' => [%w{degF farenheit Farenheit}, 1.8, :temperature, %w{<kelvin>}],
99
- '<rankine>' => [%w{degR rankine Rankine}, 1.8, :temperature, %w{<kelvin>}],
100
- '<temp-K>' => [%w{tempK}, 1.0, :temperature, %w{<kelvin>}],
101
- '<temp-C>' => [%w{tempC}, 1.0, :temperature, %w{<kelvin>}],
102
- '<temp-F>' => [%w{tempF}, 1.0, :temperature, %w{<kelvin>}],
103
- '<temp-R>' => [%w{tempR}, 1.0, :temperature, %w{<kelvin>}],
96
+ '<kelvin>' => [%w{degK kelvin}, 1.0, :temperature, %w{<kelvin>}],
97
+ '<celsius>' => [%w{degC celsius celsius centigrade}, 1.0, :temperature, %w{<kelvin>}],
98
+ '<fahrenheit>' => [%w{degF fahrenheit}, 1/1.8, :temperature, %w{<kelvin>}],
99
+ '<rankine>' => [%w{degR rankine}, 1/1.8, :temperature, %w{<kelvin>}],
100
+ '<temp-K>' => [%w{tempK}, 1.0, :temperature, %w{<temp-K>}],
101
+ '<temp-C>' => [%w{tempC}, 1.0, :temperature, %w{<temp-K>}],
102
+ '<temp-F>' => [%w{tempF}, 1/1.8, :temperature, %w{<temp-K>}],
103
+ '<temp-R>' => [%w{tempR}, 1/1.8, :temperature, %w{<temp-K>}],
104
104
 
105
105
  #time
106
106
  '<second>'=> [%w{s sec second seconds}, 1.0, :time, %w{<second>}],
@@ -9,7 +9,7 @@ require 'chronic'
9
9
 
10
10
  class Unit < Numeric
11
11
  @@USER_DEFINITIONS = {'<inchworm>' => [%w{inworm inchworm}, 0.0254, :length, %w{<meter>} ],
12
- '<habenero>' => [%{degH}, 100, :temperature, %w{<celcius>}]}
12
+ '<habenero>' => [%{degH}, 100, :temperature, %w{<celsius>}]}
13
13
  Unit.setup
14
14
  end
15
15
 
@@ -106,6 +106,7 @@ class TestRubyUnits < Test::Unit::TestCase
106
106
  assert_equal @april_fools.unit.to_time, @april_fools
107
107
  assert_equal Time.in('1 day'), @april_fools + 86400
108
108
  assert_equal @april_fools_datetime.inspect, "2006-04-01T12:00:00Z"
109
+ assert_equal '2453826.5 days'.unit.to_datetime.to_s, "2006-04-01T00:00:00Z"
109
110
  end
110
111
 
111
112
  def test_string_helpers
@@ -565,60 +566,40 @@ class TestRubyUnits < Test::Unit::TestCase
565
566
  end
566
567
 
567
568
  def test_temperature_conversions
568
- assert_in_delta '0 tempC'.unit.scalar, '273.15 degK'.unit.scalar, 0.01
569
- assert_in_delta '0 tempF'.unit.scalar, '255.37 degK'.unit.scalar, 0.01
570
- assert_in_delta '0 tempK'.unit.scalar, '0 degK'.unit.scalar, 0.01
571
- assert_in_delta '0 tempR'.unit.scalar, '0 degK'.unit.scalar, 0.01
572
-
573
- unit1 = Unit.new("37 degC")
574
- unit2 = unit1 >> "tempF"
575
- assert_in_delta 98.6, unit2.scalar, 0.1
576
- unit2 = unit1 >> "tempK"
577
- assert_in_delta 310.15, unit2.scalar, 0.01
578
- unit2 = unit1 >> "tempR"
579
- assert_in_delta 558.27, unit2.scalar, 0.01
580
- unit3 = Unit.new("1 J/degC")
581
- assert_in_delta 1, (unit3 >> "J/degK").scalar, 0.01
582
-
583
- unit1 = Unit.new("98.6 degF")
584
- unit2 = unit1 >> "tempC"
585
- assert_in_delta 37, unit2.scalar, 0.1
586
- unit2 = unit1 >> "tempK"
587
- assert_in_delta 310.15, unit2.scalar, 0.01
588
- unit2 = unit1 >> "tempR"
589
- assert_in_delta 558.27, unit2.scalar, 0.01
590
- unit3 = Unit.new("1 J/degC")
591
- assert_in_delta 1, (unit3 >> "J/degK").scalar, 0.01
569
+ assert_raises(ArgumentError) { '-1 tempK'.unit}
570
+ assert_raises(ArgumentError) { '-1 tempR'.unit}
571
+ assert_raises(ArgumentError) { '-1000 tempC'.unit}
572
+ assert_raises(ArgumentError) { '-1000 tempF'.unit}
592
573
 
593
- unit1 = Unit.new("310.15 degK")
594
- unit2 = unit1 >> "tempF"
595
- assert_in_delta 98.6, unit2.scalar, 0.1
596
- unit2 = unit1 >> "tempC"
597
- assert_in_delta 37, unit2.scalar, 0.01
598
- unit2 = unit1 >> "tempR"
599
- assert_in_delta 558.27, unit2.scalar, 0.01
600
- unit3 = Unit.new("1 J/degC")
601
- assert_in_delta 1, (unit3 >> "J/degK").scalar, 0.01
574
+ assert_equal '0 tempC'.unit, '32 tempF'.unit
575
+ assert_equal '0 tempC'.unit, '273.15 tempK'.unit
576
+ assert_in_delta '0 tempC'.unit.base_scalar, '491.67 tempR'.unit.base_scalar, 0.01
602
577
 
603
- unit1 = Unit.new("558.27 degR")
604
- unit2 = unit1 >> "tempC"
605
- assert_in_delta 37, unit2.scalar, 0.1
606
- unit2 = unit1 >> "tempK"
607
- assert_in_delta 310.15, unit2.scalar, 0.01
608
- unit2 = unit1 >> "tempF"
609
- assert_in_delta 98.6, unit2.scalar, 0.01
610
- assert_in_delta 558.27, unit1.to("tempR").scalar, 0.01
611
- unit3 = Unit.new("1 J/degC")
612
- assert_in_delta 1, (unit3 >> "J/degK").scalar, 0.01
578
+ a = '10 degC'.unit
579
+ assert_equal a >> 'tempC', '-263.15 tempC'.unit
580
+ assert_equal a >> 'tempK', '10 tempK'.unit
581
+ assert_equal a >> 'tempR', '18 tempR'.unit
582
+ assert_equal a >> 'tempF', '-441.67 tempF'.unit
613
583
 
614
- # round trip conversions
615
- unit1 = Unit "37 degC"
616
- unit2 = unit1 >> "degF" >> 'degK' >> 'degR' >> 'degC'
617
- assert_equal unit2, unit1
618
-
619
- unit1 = Unit "37 degC"
584
+ unit1 = '37 tempC'.unit
620
585
  unit2 = unit1 >> "tempF" >> 'tempK' >> 'tempR' >> 'tempC'
621
- assert_equal unit2, unit1
586
+ assert_equal unit1 >> 'tempF' >> 'tempK' >> 'tempR' >> 'tempC', unit1
587
+
588
+ a = '100 tempF'.unit
589
+ b = '10 degC'.unit
590
+ c = '50 tempF'.unit
591
+ d = '18 degF'.unit
592
+ assert_equal a+b, '118 tempF'.unit
593
+ assert_equal b+a, '118 tempF'.unit
594
+ assert_equal a-b, '82 tempF'.unit
595
+ assert_in_delta (a-c).scalar, '50 degF'.unit.scalar, 0.01
596
+ assert_equal b+d, '20 degC'.unit
597
+
598
+ assert_raises(ArgumentError) { a * b }
599
+ assert_raises(ArgumentError) { a / b }
600
+ assert_raises(ArgumentError) { a ** 2 }
601
+ assert_raises(ArgumentError) { c - '400 degK'.unit}
602
+ assert_equal a, a.to('tempF')
622
603
  end
623
604
 
624
605
  def test_feet
@@ -702,8 +683,8 @@ class TestRubyUnits < Test::Unit::TestCase
702
683
  v = Unit "1 m^3"
703
684
  n = Unit "1 mole"
704
685
  r = Unit "8.31451 J/mol*degK"
705
- t = ((p*v)/(n*r)).to("tempF")
706
- assert_in_delta 21189.2,t.scalar, 0.1
686
+ t = ((p*v)/(n*r)).to('tempK')
687
+ assert_in_delta 12027.16,t.base_scalar, 0.1
707
688
  end
708
689
 
709
690
 
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
2
+ rubygems_version: 0.9.1
3
3
  specification_version: 1
4
4
  name: ruby-units
5
5
  version: !ruby/object:Gem::Version
6
- version: 1.0.2
7
- date: 2007-01-24 00:00:00 -05:00
6
+ version: 1.1.0
7
+ date: 2007-01-28 00:00:00 -05:00
8
8
  summary: A model that performs unit conversions and unit math
9
9
  require_paths:
10
10
  - lib