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.
- data/CHANGELOG.txt +4 -0
- data/README.txt +34 -2
- data/lib/ruby_units/ruby-units.rb +90 -51
- data/lib/ruby_units/units.rb +9 -9
- data/test/test_ruby-units.rb +34 -53
- metadata +3 -3
data/CHANGELOG.txt
CHANGED
@@ -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
|
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
|
-
|
67
|
+
FAHRENHEIT = ['<fahrenheit>']
|
80
68
|
RANKINE = ['<rankine>']
|
81
|
-
|
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.
|
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 &&
|
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
|
-
|
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
|
-
|
453
|
-
|
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
|
-
|
473
|
-
|
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,
|
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.
|
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
|
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
|
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
|
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
|
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
|
-
|
651
|
-
|
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
|
-
|
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.
|
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
|
|
data/lib/ruby_units/units.rb
CHANGED
@@ -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
|
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
|
97
|
-
'<
|
98
|
-
'<
|
99
|
-
'<rankine>' => [%w{degR rankine
|
100
|
-
'<temp-K>' => [%w{tempK}, 1.0, :temperature, %w{<
|
101
|
-
'<temp-C>' => [%w{tempC}, 1.0, :temperature, %w{<
|
102
|
-
'<temp-F>' => [%w{tempF}, 1.
|
103
|
-
'<temp-R>' => [%w{tempR}, 1.
|
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>}],
|
data/test/test_ruby-units.rb
CHANGED
@@ -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{<
|
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
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
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
|
-
|
594
|
-
|
595
|
-
assert_in_delta
|
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
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
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
|
-
|
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
|
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(
|
706
|
-
assert_in_delta
|
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.
|
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
|
7
|
-
date: 2007-01-
|
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
|