ruby-units 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- 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