ruby-units 0.2.0 → 0.2.1
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 +36 -1
- data/README +43 -8
- data/lib/ruby-units.rb +218 -21
- data/test/test_ruby-units.rb +1 -2
- metadata +1 -1
data/CHANGELOG
CHANGED
@@ -57,5 +57,40 @@ Change Log for Ruby-units
|
|
57
57
|
=> Sat Sep 23 04:26:40 EDT 2006
|
58
58
|
* Time.now.unit => 1.159e9 s
|
59
59
|
* works well with 'Uncertain' numerics
|
60
|
+
(www.rubyforge.org/projects/uncertain)
|
60
61
|
* Improved parsing
|
61
|
-
|
62
|
+
|
63
|
+
2006-09-18 0.2.1 * Trig math functions (sin, cos, tan, sinh, cosh, tanh)
|
64
|
+
accept units that can be converted to radians
|
65
|
+
Math.sin("90 deg".unit) => 1.0
|
66
|
+
* Date and DateTime can be offset by a time unit
|
67
|
+
(Date.today + "1 day".unit) => 2006-09-19
|
68
|
+
Does not work with months since they aren't a consistent
|
69
|
+
size
|
70
|
+
* Tweaked time usage a bit
|
71
|
+
Time.now + "1 hr".unit => Mon Sep 18 11:51:29 EDT 2006
|
72
|
+
* can output time in 'hh:mm:ss' format by using
|
73
|
+
'unit.to_s(:time)'
|
74
|
+
* added time helper methods
|
75
|
+
ago,
|
76
|
+
since(Time/DateTime),
|
77
|
+
until(Time/DateTime),
|
78
|
+
from(Time/DateTime),
|
79
|
+
before(Time/DateTime), and
|
80
|
+
after(Time/DateTime)
|
81
|
+
* Time helpers also work on strings. In this case they
|
82
|
+
are first converted to units
|
83
|
+
'5 min'.from_now
|
84
|
+
'1 week'.ago
|
85
|
+
'min'.since(time)
|
86
|
+
'min'.until(time)
|
87
|
+
'1 day'.from()
|
88
|
+
* Can pass Strings to time helpers and they will be parsed
|
89
|
+
with ParseDate
|
90
|
+
* Fixed most parsing bugs (I think)
|
91
|
+
* Can pass a strftime format string to to_s to format time
|
92
|
+
output
|
93
|
+
* can use U'1 mm' or '1 mm'.u to specify units now
|
94
|
+
*
|
95
|
+
|
96
|
+
|
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
=Ruby Units
|
2
2
|
|
3
|
-
Version: 0.1
|
3
|
+
Version: 0.2.1
|
4
4
|
|
5
5
|
Kevin C. Olbrich, Ph.D.
|
6
6
|
|
@@ -29,6 +29,11 @@ This package may be installed using:
|
|
29
29
|
unit = Unit("1 mm") # shorthand
|
30
30
|
unit = "1 mm".to_unit # convert string object
|
31
31
|
unit = object.to_unit # convert any object using object.to_s
|
32
|
+
unit = U'1 mm'
|
33
|
+
unit = u'1 mm'
|
34
|
+
unit = '1 mm'.unit
|
35
|
+
unit = '1 mm'.u
|
36
|
+
|
32
37
|
|
33
38
|
==Rules:
|
34
39
|
1. only 1 quantity per unit (with 2 exceptions... 6'5" and '8 lbs 8 oz')
|
@@ -69,8 +74,11 @@ Units can be converted to other units in a couple of ways.
|
|
69
74
|
unit >>= "ft" # => convert and overwrite original object
|
70
75
|
unit3 = unit1 + unit2 # => resulting object will have the units of unit1
|
71
76
|
unit3 = unit1 - unit2 # => resulting object will have the units of unit1
|
72
|
-
unit1 <=> unit2 # => does comparison on quantities in base units,
|
73
|
-
|
77
|
+
unit1 <=> unit2 # => does comparison on quantities in base units,
|
78
|
+
throws an exception if not compatible
|
79
|
+
unit1 === unit2 # => true if units and quantity are the same, even if
|
80
|
+
'equivalent' by <=>
|
81
|
+
unit.to('ft') # convert
|
74
82
|
|
75
83
|
==Text Output
|
76
84
|
Units will display themselves nicely based on the preferred abbreviation for the units and prefixes.
|
@@ -78,8 +86,35 @@ Since Unit implements a Unit#to_s, all that is needed in most cases is:
|
|
78
86
|
"#{Unit.new('1 mm')}" #=> "1 mm"
|
79
87
|
|
80
88
|
The to_s also accepts some options.
|
81
|
-
Unit.new('1.5 mm').to_s("%0.2f") # => "1.50 mm". Enter any valid format
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
89
|
+
Unit.new('1.5 mm').to_s("%0.2f") # => "1.50 mm". Enter any valid format
|
90
|
+
string. Also accepts strftime format
|
91
|
+
U('1.5 mm').to_s("in") # => converts to inches before printing
|
92
|
+
U("2 m").to_s(:ft) #=> returns 6'7"
|
93
|
+
U("100 kg").to_s(:lbs) #=> returns 220 lbs, 7 oz
|
94
|
+
|
95
|
+
|
96
|
+
==Time Helpers
|
97
|
+
|
98
|
+
Time, Date, and DateTime objects can have time units added or subtracted.
|
99
|
+
|
100
|
+
Time.now + "10 min".u
|
101
|
+
|
102
|
+
Several helpers have also been defined.
|
103
|
+
|
104
|
+
'min'.since('9/18/06 3:00pm')
|
105
|
+
'min'.before('9/18/08 3:00pm')
|
106
|
+
'days'.until('1/1/07')
|
107
|
+
'5 min'.from(Time.now)
|
108
|
+
'5 min'.from_now
|
109
|
+
'5 min'.before_now
|
110
|
+
'5 min'.before(Time.now)
|
111
|
+
'10 min'.ago
|
112
|
+
|
113
|
+
==Ranges
|
114
|
+
|
115
|
+
[U('0 h')..U('10 h')].each {|x| p x}
|
116
|
+
works so long as the starting point has an integer scalar
|
117
|
+
|
118
|
+
==Math functions
|
119
|
+
All Trig math functions (sin, cos, sinh, ...) can take a unit as their parameter. It will be converted to radians and then used if possible.
|
120
|
+
|
data/lib/ruby-units.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'mathn'
|
2
2
|
require 'rational'
|
3
|
-
|
4
|
-
|
3
|
+
require 'date'
|
4
|
+
require 'parsedate'
|
5
|
+
# = Ruby Units 0.2.1
|
5
6
|
#
|
6
7
|
# Copyright 2006 by Kevin C. Olbrich, Ph.D.
|
7
8
|
#
|
@@ -185,10 +186,16 @@ class Unit < Numeric
|
|
185
186
|
when :lbs:
|
186
187
|
ounces = self.to("oz").scalar
|
187
188
|
"#{(ounces / 16).truncate} lbs, #{(ounces % 16).round} oz"
|
189
|
+
when String
|
190
|
+
begin #first try a standard format string
|
191
|
+
target_units =~ /(%[\w\d#+-.]*)*\s*(.+)*/
|
192
|
+
return self.to($2).to_s($1) if $2
|
193
|
+
"#{($1 || '%g') % @scalar || 0} #{self.units}".strip
|
194
|
+
rescue #if that is malformed, try a time string
|
195
|
+
return (Time.gm(0) + self).strftime(target_units)
|
196
|
+
end
|
188
197
|
else
|
189
|
-
|
190
|
-
return self.to($2).to_s($1) if $2
|
191
|
-
"#{($1 || '%g') % @scalar || 0} #{self.units}".strip
|
198
|
+
"#{'%g' % @scalar} #{self.units}".strip
|
192
199
|
end
|
193
200
|
end
|
194
201
|
|
@@ -260,9 +267,11 @@ class Unit < Numeric
|
|
260
267
|
else
|
261
268
|
raise ArgumentError, "Incompatible Units"
|
262
269
|
end
|
270
|
+
elsif Time === other
|
271
|
+
other + self
|
263
272
|
else
|
264
273
|
x,y = coerce(other)
|
265
|
-
|
274
|
+
y + x
|
266
275
|
end
|
267
276
|
end
|
268
277
|
|
@@ -276,6 +285,8 @@ class Unit < Numeric
|
|
276
285
|
else
|
277
286
|
raise ArgumentError, "Incompatible Units"
|
278
287
|
end
|
288
|
+
elsif Time === other
|
289
|
+
other + self
|
279
290
|
else
|
280
291
|
x,y = coerce(other)
|
281
292
|
x - y
|
@@ -360,7 +371,7 @@ class Unit < Numeric
|
|
360
371
|
raise ArgumentError, "Illegal root" unless vec.max == 0
|
361
372
|
num = @numerator.clone
|
362
373
|
den = @denominator.clone
|
363
|
-
|
374
|
+
|
364
375
|
@numerator.uniq.each do |item|
|
365
376
|
x = num.find_all {|i| i==item}.size
|
366
377
|
r = ((x/n)*(n-1)).to_int
|
@@ -372,8 +383,8 @@ class Unit < Numeric
|
|
372
383
|
r = ((x/n)*(n-1)).to_int
|
373
384
|
r.times {|x| den.delete_at(den.index(item))}
|
374
385
|
end
|
375
|
-
q = @scalar**(1/n)
|
376
|
-
Unit.new(
|
386
|
+
q = @scalar**(1/n)
|
387
|
+
Unit.new(:scalar=>q,:numerator=>num,:denominator=>den)
|
377
388
|
end
|
378
389
|
|
379
390
|
# returns inverse of Unit (1/unit)
|
@@ -402,8 +413,8 @@ class Unit < Numeric
|
|
402
413
|
return self if FalseClass === other
|
403
414
|
if String === other && other =~ /temp(K|C|R|F)/
|
404
415
|
raise ArgumentError, "Receiver is not a temperature unit" unless self.signature==400
|
405
|
-
|
406
|
-
return self.to_base.to("tempF") if @numerator.size > 1 || @denominator != ['<1>']
|
416
|
+
return self.to_base.to(other) unless self.is_base?
|
417
|
+
#return self.to_base.to("tempF") if @numerator.size > 1 || @denominator != ['<1>']
|
407
418
|
q=case
|
408
419
|
when @numerator.include?('<celcius>'):
|
409
420
|
case other
|
@@ -535,7 +546,7 @@ class Unit < Numeric
|
|
535
546
|
{:scalar=>q, :numerator=>num.flatten.compact, :denominator=>den.flatten.compact}
|
536
547
|
end
|
537
548
|
|
538
|
-
#
|
549
|
+
# converts the unit back to a float if it is unitless
|
539
550
|
def to_f
|
540
551
|
return @scalar.to_f if self.unitless?
|
541
552
|
raise RuntimeError, "Can't convert to float unless unitless. Use Unit#scalar"
|
@@ -602,6 +613,7 @@ class Unit < Numeric
|
|
602
613
|
Unit.new([@scalar.to_int, @numerator, @denominator])
|
603
614
|
end
|
604
615
|
|
616
|
+
# Tries to make a Time object from current unit
|
605
617
|
def to_time
|
606
618
|
Time.at(self)
|
607
619
|
end
|
@@ -617,6 +629,59 @@ class Unit < Numeric
|
|
617
629
|
def zero?
|
618
630
|
return @scalar.zero?
|
619
631
|
end
|
632
|
+
|
633
|
+
# '5 min'.unit.ago
|
634
|
+
def ago
|
635
|
+
Time.now - self
|
636
|
+
end
|
637
|
+
|
638
|
+
# '5 min'.before(time)
|
639
|
+
def before(time_point = ::Time.now)
|
640
|
+
raise ArgumentError, "Must specify a Time" unless time_point
|
641
|
+
if String === time_point
|
642
|
+
Time.local(*ParseDate.parsedate(time_point))-self
|
643
|
+
else
|
644
|
+
time_point - self
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
# 'min'.since(time)
|
649
|
+
def since(time_point = ::Time.now)
|
650
|
+
case time_point
|
651
|
+
when Time: (Time.now - time_point).unit('s').to(self)
|
652
|
+
when DateTime: (DateTime.now - time_point).unit('d').to(self)
|
653
|
+
when String: (Time.now - Time.local(*ParseDate.parsedate(time_point))).unit('s').to(self)
|
654
|
+
else
|
655
|
+
raise ArgumentError, "Must specify a Time" unless time_point
|
656
|
+
end
|
657
|
+
end
|
658
|
+
|
659
|
+
# 'min'.until(time)
|
660
|
+
def until(time_point = ::Time.now)
|
661
|
+
case time_point
|
662
|
+
when Time: (time_point - Time.now).unit('s').to(self)
|
663
|
+
when DateTime: (time_point - DateTime.now).unit('d').to(self)
|
664
|
+
when String: (Time.local(*ParseDate.parsedate(time_point)) - Time.now).unit('s').to(self)
|
665
|
+
else
|
666
|
+
raise ArgumentError, "Must specify a Time" unless time_point
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
# '5 min'.from_now
|
671
|
+
def from_now
|
672
|
+
self.from
|
673
|
+
end
|
674
|
+
|
675
|
+
# '5 min'.from(time)
|
676
|
+
def from(time_point = ::Time.now)
|
677
|
+
raise ArgumentError, "Must specify a Time" unless time_point
|
678
|
+
if String === time_point
|
679
|
+
Time.local(*ParseDate.parsedate(time_point))+self
|
680
|
+
else
|
681
|
+
time_point + self
|
682
|
+
end
|
683
|
+
end
|
684
|
+
alias :after :from
|
620
685
|
|
621
686
|
def succ
|
622
687
|
raise ArgumentError, "Non Integer Scalar" unless @scalar == @scalar.to_i
|
@@ -705,17 +770,17 @@ class Unit < Numeric
|
|
705
770
|
@scalar = @scalar.to_f
|
706
771
|
end
|
707
772
|
|
708
|
-
@numerator = top.scan(/(
|
709
|
-
@denominator = bottom.scan(/(
|
773
|
+
@numerator = top.scan(/(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/).delete_if {|x| x.empty?}.compact if top
|
774
|
+
@denominator = bottom.scan(/(#{@@PREFIX_REGEX})*?(#{@@UNIT_REGEX})\b/).delete_if {|x| x.empty?}.compact if bottom
|
710
775
|
|
711
776
|
@numerator = @numerator.map do |item|
|
712
777
|
item.map {|x| Regexp.escape(x) if x}
|
713
|
-
|
778
|
+
@@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
|
714
779
|
end.flatten.compact.delete_if {|x| x.empty?}
|
715
780
|
|
716
781
|
@denominator = @denominator.map do |item|
|
717
782
|
item.map {|x| Regexp.escape(x) if x}
|
718
|
-
@@
|
783
|
+
@@PREFIX_MAP[item[0]] ? [@@PREFIX_MAP[item[0]], @@UNIT_MAP[item[1]]] : [@@UNIT_MAP[item[1]]]
|
719
784
|
end.flatten.compact.delete_if {|x| x.empty?}
|
720
785
|
|
721
786
|
@numerator = ['<1>'] if @numerator.empty?
|
@@ -724,43 +789,77 @@ class Unit < Numeric
|
|
724
789
|
end
|
725
790
|
end
|
726
791
|
|
792
|
+
# Need the 'Uncertain' gem for this to do anything helpful
|
727
793
|
if defined? Uncertain
|
728
794
|
class Uncertain
|
729
795
|
def to_unit(other=nil)
|
730
796
|
other ? Unit.new(self).to(other) : Unit.new(self)
|
731
797
|
end
|
798
|
+
alias :unit :to_unit
|
799
|
+
alias :u :to_unit
|
732
800
|
end
|
733
801
|
end
|
734
802
|
|
735
803
|
|
804
|
+
# Allow date objects to do offsets by a time unit
|
805
|
+
# Date.today + U"1 week" => gives today+1 week
|
806
|
+
class Date
|
807
|
+
alias :unit_date_add :+
|
808
|
+
def +(unit)
|
809
|
+
if Unit === unit
|
810
|
+
unit_date_add(unit.to('day').scalar)
|
811
|
+
else
|
812
|
+
unit_date_add(unit)
|
813
|
+
end
|
814
|
+
end
|
815
|
+
|
816
|
+
alias :unit_date_sub :-
|
817
|
+
def -(unit)
|
818
|
+
if Unit === unit
|
819
|
+
unit_date_sub(unit.to('day').scalar)
|
820
|
+
else
|
821
|
+
unit_date_sub(unit)
|
822
|
+
end
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
736
826
|
class Object
|
737
827
|
def Unit(other)
|
738
828
|
other.to_unit
|
739
829
|
end
|
830
|
+
alias :U :Unit
|
831
|
+
alias :u :Unit
|
740
832
|
end
|
741
833
|
|
834
|
+
# make a unitless unit with a given scalar
|
742
835
|
class Numeric
|
743
836
|
def to_unit(other = nil)
|
744
837
|
other ? Unit.new(self) * Unit.new(other) : Unit.new(self)
|
745
838
|
end
|
746
839
|
alias :unit :to_unit
|
840
|
+
alias :u :to_unit
|
747
841
|
end
|
748
842
|
|
749
|
-
|
843
|
+
# make a unit from an array
|
844
|
+
# [1, 'mm'].unit => 1 mm
|
750
845
|
class Array
|
751
846
|
def to_unit(other = nil)
|
752
847
|
other ? Unit.new(self).to(other) : Unit.new(self)
|
753
848
|
end
|
754
849
|
alias :unit :to_unit
|
850
|
+
alias :u :to_unit
|
755
851
|
end
|
756
852
|
|
853
|
+
# make a string into a unit
|
757
854
|
class String
|
758
855
|
def to_unit(other = nil)
|
759
856
|
other ? Unit.new(self) >> other : Unit.new(self)
|
760
857
|
end
|
761
858
|
alias :unit :to_unit
|
859
|
+
alias :u :to_unit
|
762
860
|
alias :unit_format :%
|
763
861
|
|
862
|
+
# format unit output using formating codes '%0.2f' % '1 mm'.unit => '1.00 mm'
|
764
863
|
def %(*args)
|
765
864
|
if Unit === args[0]
|
766
865
|
args[0].to_s(self)
|
@@ -768,8 +867,37 @@ class String
|
|
768
867
|
unit_format(*args)
|
769
868
|
end
|
770
869
|
end
|
870
|
+
|
871
|
+
def from(time_point = ::Time.now)
|
872
|
+
self.unit.from(time_point)
|
873
|
+
end
|
874
|
+
alias :after :from
|
875
|
+
alias :from_now :from
|
876
|
+
|
877
|
+
def ago
|
878
|
+
self.unit.ago
|
879
|
+
end
|
880
|
+
|
881
|
+
def before(time_point = ::Time.now)
|
882
|
+
self.unit.before(time_point)
|
883
|
+
end
|
884
|
+
alias :before_now :before
|
885
|
+
|
886
|
+
def since(time_point = ::Time.now)
|
887
|
+
self.unit.since(time_point)
|
888
|
+
end
|
889
|
+
|
890
|
+
def until(time_point = ::Time.now)
|
891
|
+
self.unit.until(time_point)
|
892
|
+
end
|
893
|
+
|
894
|
+
def to(other)
|
895
|
+
self.unit.to(other)
|
896
|
+
end
|
771
897
|
end
|
772
898
|
|
899
|
+
|
900
|
+
# Allow time objects to use
|
773
901
|
class Time
|
774
902
|
|
775
903
|
class << self
|
@@ -785,14 +913,14 @@ class Time
|
|
785
913
|
end
|
786
914
|
|
787
915
|
def to_unit(other = "s")
|
788
|
-
other ? Unit.new(self.to_f)
|
916
|
+
other ? Unit.new("#{self.to_f} s").to(other) : Unit.new("#{self.to_f} s")
|
789
917
|
end
|
790
918
|
alias :unit :to_unit
|
791
|
-
|
919
|
+
alias :u :to_unit
|
792
920
|
alias :unit_add :+
|
793
921
|
def +(other)
|
794
922
|
if Unit === other
|
795
|
-
|
923
|
+
unit_add(other.to('s').scalar)
|
796
924
|
else
|
797
925
|
unit_add(other)
|
798
926
|
end
|
@@ -801,9 +929,78 @@ class Time
|
|
801
929
|
alias :unit_sub :-
|
802
930
|
def -(other)
|
803
931
|
if Unit === other
|
804
|
-
|
932
|
+
unit_sub(other.to('s').scalar)
|
805
933
|
else
|
806
934
|
unit_sub(other)
|
807
935
|
end
|
808
936
|
end
|
937
|
+
end
|
938
|
+
|
939
|
+
module Math
|
940
|
+
alias unit_sin sin
|
941
|
+
def sin(n)
|
942
|
+
if Unit === n
|
943
|
+
unit_sin(n.to('radian').scalar)
|
944
|
+
else
|
945
|
+
unit_sin(n)
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
alias unit_cos cos
|
950
|
+
def cos(n)
|
951
|
+
if Unit === n
|
952
|
+
unit_cos(n.to('radian').scalar)
|
953
|
+
else
|
954
|
+
unit_cos(n)
|
955
|
+
end
|
956
|
+
end
|
957
|
+
|
958
|
+
alias unit_sinh sinh
|
959
|
+
def sinh(n)
|
960
|
+
if Unit === n
|
961
|
+
unit_sinh(n.to('radian').scalar)
|
962
|
+
else
|
963
|
+
unit_sinh(n)
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
alias unit_cosh cosh
|
968
|
+
def cosh(n)
|
969
|
+
if Unit === n
|
970
|
+
unit_cosh(n.to('radian').scalar)
|
971
|
+
else
|
972
|
+
unit_cosh(n)
|
973
|
+
end
|
974
|
+
end
|
975
|
+
|
976
|
+
alias unit_tan tan
|
977
|
+
def tan(n)
|
978
|
+
if Unit === n
|
979
|
+
unit_tan(n.to('radian').scalar)
|
980
|
+
else
|
981
|
+
unit_tan(n)
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
alias unit_tanh tanh
|
986
|
+
def tanh(n)
|
987
|
+
if Unit === n
|
988
|
+
unit_tanh(n.to('radian').scalar)
|
989
|
+
else
|
990
|
+
unit_tanh(n)
|
991
|
+
end
|
992
|
+
end
|
993
|
+
|
994
|
+
module_function :unit_sin
|
995
|
+
module_function :sin
|
996
|
+
module_function :unit_cos
|
997
|
+
module_function :cos
|
998
|
+
module_function :unit_sinh
|
999
|
+
module_function :sinh
|
1000
|
+
module_function :unit_cosh
|
1001
|
+
module_function :cosh
|
1002
|
+
module_function :unit_tan
|
1003
|
+
module_function :tan
|
1004
|
+
module_function :unit_tanh
|
1005
|
+
module_function :tanh
|
809
1006
|
end
|
data/test/test_ruby-units.rb
CHANGED
@@ -447,7 +447,6 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
447
447
|
assert_in_delta 558.27, unit1.to("tempR").scalar, 0.01
|
448
448
|
unit3 = Unit.new("1 J/degC")
|
449
449
|
assert_in_delta 1, (unit3 >> "J/degK").scalar, 0.01
|
450
|
-
assert_raises(ArgumentError) {"10 degH".unit >> "tempF"}
|
451
450
|
|
452
451
|
# round trip conversions
|
453
452
|
unit1 = Unit "37 degC"
|
@@ -562,7 +561,7 @@ class TestRubyUnits < Test::Unit::TestCase
|
|
562
561
|
def test_inspect
|
563
562
|
unit1 = Unit "1 mm"
|
564
563
|
assert_equal "1 mm", unit1.inspect
|
565
|
-
assert_not_equal "1 mm", unit1.inspect(:dump)
|
564
|
+
assert_not_equal "1.0 mm", unit1.inspect(:dump)
|
566
565
|
end
|
567
566
|
|
568
567
|
def test_to_f
|
metadata
CHANGED