ruby-units 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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