ruby-units 2.3.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,10 @@ class RubyUnits::Unit < Numeric
16
16
  # @return [Array]
17
17
  attr_accessor :denominator
18
18
 
19
+ # Unit name to be used when generating output. This MUST be a parseable
20
+ # string or it won't be possible to round trip the unit to a String and
21
+ # back.
22
+ #
19
23
  # @return [String]
20
24
  attr_accessor :display_name
21
25
 
@@ -48,7 +52,7 @@ class RubyUnits::Unit < Numeric
48
52
  end
49
53
 
50
54
  # set the name, strip off '<' and '>'
51
- # @param [String]
55
+ # @param name_value [String]
52
56
  # @return [String]
53
57
  def name=(name_value)
54
58
  @name = name_value.gsub(/[<>]/, '')
@@ -57,7 +61,7 @@ class RubyUnits::Unit < Numeric
57
61
  # alias array must contain the name of the unit and entries must be unique
58
62
  # @return [Array]
59
63
  def aliases
60
- [[@aliases], @name].flatten.compact.uniq
64
+ [[@aliases], @name, @display_name].flatten.compact.uniq
61
65
  end
62
66
 
63
67
  # define a unit in terms of another unit
@@ -1,125 +1,148 @@
1
- # Math will convert unit objects to radians and then attempt to use the value for
2
- # trigonometric functions.
3
- module Math
4
- alias unit_sqrt sqrt
5
- # @return [Numeric]
6
- def sqrt(n)
7
- if n.is_a?(RubyUnits::Unit)
8
- (n**Rational(1, 2)).to_unit
9
- else
10
- unit_sqrt(n)
1
+ module RubyUnits
2
+ # Math will convert unit objects to radians and then attempt to use the value for
3
+ # trigonometric functions.
4
+ module Math
5
+ # Take the square root of a unit or number
6
+ #
7
+ # @param number [Numeric, RubyUnits::Unit]
8
+ # @return [Numeric, RubyUnits::Unit]
9
+ def sqrt(number)
10
+ if number.is_a?(RubyUnits::Unit)
11
+ (number**Rational(1, 2)).to_unit
12
+ else
13
+ super
14
+ end
11
15
  end
12
- end
13
- # @return [Numeric]
14
- module_function :unit_sqrt
15
- # @return [Numeric]
16
- module_function :sqrt
17
-
18
- #:nocov:
19
- if respond_to?(:cbrt)
20
- alias unit_cbrt cbrt
16
+
17
+ # Take the cube root of a unit or number
18
+ #
19
+ # @param number [Numeric, RubyUnits::Unit]
20
+ # @return [Numeric, RubyUnits::Unit]
21
+ def cbrt(number)
22
+ if number.is_a?(RubyUnits::Unit)
23
+ (number**Rational(1, 3)).to_unit
24
+ else
25
+ super
26
+ end
27
+ end
28
+
29
+ # @param angle [Numeric, RubyUnits::Unit]
21
30
  # @return [Numeric]
22
- def cbrt(n)
23
- if RubyUnits::Unit === n
24
- (n**Rational(1, 3)).to_unit
31
+ def sin(angle)
32
+ angle.is_a?(RubyUnits::Unit) ? super(angle.convert_to('radian').scalar) : super
33
+ end
34
+
35
+ # @param number [Numeric, RubyUnits::Unit]
36
+ # @return [Numeric, RubyUnits::Unit]
37
+ def asin(number)
38
+ if number.is_a?(RubyUnits::Unit)
39
+ [super(number), 'radian'].to_unit
25
40
  else
26
- unit_cbrt(n)
41
+ super
27
42
  end
28
43
  end
44
+
45
+ # @param angle [Numeric, RubyUnits::Unit]
29
46
  # @return [Numeric]
30
- module_function :unit_cbrt
47
+ def cos(angle)
48
+ angle.is_a?(RubyUnits::Unit) ? super(angle.convert_to('radian').scalar) : super
49
+ end
50
+
51
+ # @param number [Numeric, RubyUnits::Unit]
52
+ # @return [Numeric, RubyUnits::Unit]
53
+ def acos(number)
54
+ if number.is_a?(RubyUnits::Unit)
55
+ [super(number), 'radian'].to_unit
56
+ else
57
+ super
58
+ end
59
+ end
60
+
61
+ # @param number [Numeric, RubyUnits::Unit]
31
62
  # @return [Numeric]
32
- module_function :cbrt
33
- end
34
- #:nocov:
63
+ def sinh(number)
64
+ number.is_a?(RubyUnits::Unit) ? super(number.convert_to('radian').scalar) : super
65
+ end
35
66
 
36
- alias unit_sin sin
37
- # @return [Numeric]
38
- def sin(n)
39
- RubyUnits::Unit === n ? unit_sin(n.convert_to('radian').scalar) : unit_sin(n)
40
- end
41
- # @return [Numeric]
42
- module_function :unit_sin
43
- # @return [Numeric]
44
- module_function :sin
45
-
46
- alias unit_cos cos
47
- # @return [Numeric]
48
- def cos(n)
49
- RubyUnits::Unit === n ? unit_cos(n.convert_to('radian').scalar) : unit_cos(n)
50
- end
51
- # @return [Numeric]
52
- module_function :unit_cos
53
- # @return [Numeric]
54
- module_function :cos
55
-
56
- alias unit_sinh sinh
57
- # @return [Numeric]
58
- def sinh(n)
59
- RubyUnits::Unit === n ? unit_sinh(n.convert_to('radian').scalar) : unit_sinh(n)
60
- end
61
- # @return [Numeric]
62
- module_function :unit_sinh
63
- # @return [Numeric]
64
- module_function :sinh
65
-
66
- alias unit_cosh cosh
67
- # @return [Numeric]
68
- def cosh(n)
69
- RubyUnits::Unit === n ? unit_cosh(n.convert_to('radian').scalar) : unit_cosh(n)
70
- end
71
- # @return [Numeric]
72
- module_function :unit_cosh
73
- # @return [Numeric]
74
- module_function :cosh
75
-
76
- alias unit_tan tan
77
- # @return [Numeric]
78
- def tan(n)
79
- RubyUnits::Unit === n ? unit_tan(n.convert_to('radian').scalar) : unit_tan(n)
80
- end
81
- # @return [Numeric]
82
- module_function :tan
83
- # @return [Numeric]
84
- module_function :unit_tan
85
-
86
- alias unit_tanh tanh
87
- # @return [Numeric]
88
- def tanh(n)
89
- RubyUnits::Unit === n ? unit_tanh(n.convert_to('radian').scalar) : unit_tanh(n)
90
- end
91
- # @return [Numeric]
92
- module_function :unit_tanh
93
- # @return [Numeric]
94
- module_function :tanh
95
-
96
- alias unit_hypot hypot
97
- # Convert parameters to consistent units and perform the function
98
- # @return [Numeric]
99
- def hypot(x, y)
100
- if RubyUnits::Unit === x && RubyUnits::Unit === y
101
- (x**2 + y**2)**Rational(1, 2)
102
- else
103
- unit_hypot(x, y)
67
+ # @param number [Numeric, RubyUnits::Unit]
68
+ # @return [Numeric]
69
+ def cosh(number)
70
+ number.is_a?(RubyUnits::Unit) ? super(number.convert_to('radian').scalar) : super
104
71
  end
105
- end
106
- # @return [Numeric]
107
- module_function :unit_hypot
108
- # @return [Numeric]
109
- module_function :hypot
110
-
111
- alias unit_atan2 atan2
112
- # @return [Numeric]
113
- def atan2(x, y)
114
- raise ArgumentError, 'Incompatible RubyUnits::Units' if (x.is_a?(RubyUnits::Unit) && y.is_a?(RubyUnits::Unit)) && !x.compatible?(y)
115
- if (x.is_a?(RubyUnits::Unit) && y.is_a?(RubyUnits::Unit)) && x.compatible?(y)
116
- Math.unit_atan2(x.base_scalar, y.base_scalar)
117
- else
118
- Math.unit_atan2(x, y)
72
+
73
+ # @param angle [Numeric, RubyUnits::Unit]
74
+ # @return [Numeric]
75
+ def tan(angle)
76
+ angle.is_a?(RubyUnits::Unit) ? super(angle.convert_to('radian').scalar) : super
77
+ end
78
+
79
+ # @param number [Numeric, RubyUnits::Unit]
80
+ # @return [Numeric]
81
+ def tanh(number)
82
+ number.is_a?(RubyUnits::Unit) ? super(number.convert_to('radian').scalar) : super
83
+ end
84
+
85
+ # @param x [Numeric, RubyUnits::Unit]
86
+ # @param y [Numeric, RubyUnits::Unit]
87
+ # @return [Numeric]
88
+ def hypot(x, y)
89
+ if x.is_a?(RubyUnits::Unit) && y.is_a?(RubyUnits::Unit)
90
+ ((x**2) + (y**2))**Rational(1, 2)
91
+ else
92
+ super
93
+ end
94
+ end
95
+
96
+ # @param number [Numeric, RubyUnits::Unit]
97
+ # @return [Numeric] if argument is a number
98
+ # @return [RubyUnits::Unit] if argument is a unit
99
+ def atan(number)
100
+ if number.is_a?(RubyUnits::Unit)
101
+ [super(number), 'radian'].to_unit
102
+ else
103
+ super
104
+ end
105
+ end
106
+
107
+ # @param x [Numeric, RubyUnits::Unit]
108
+ # @param y [Numeric, RubyUnits::Unit]
109
+ # @return [Numeric] if all parameters are numbers
110
+ # @return [RubyUnits::Unit] if parameters are units
111
+ # @raise [ArgumentError] if parameters are not numbers or compatible units
112
+ def atan2(x, y)
113
+ raise ArgumentError, 'Incompatible RubyUnits::Units' if (x.is_a?(RubyUnits::Unit) && y.is_a?(RubyUnits::Unit)) && !x.compatible?(y)
114
+
115
+ if (x.is_a?(RubyUnits::Unit) && y.is_a?(RubyUnits::Unit)) && x.compatible?(y)
116
+ [super(x.base_scalar, y.base_scalar), 'radian'].to_unit
117
+ else
118
+ super
119
+ end
120
+ end
121
+
122
+ # @param number [Numeric, RubyUnits::Unit]
123
+ # @return [Numeric]
124
+ def log10(number)
125
+ if number.is_a?(RubyUnits::Unit)
126
+ super(number.to_f)
127
+ else
128
+ super
129
+ end
130
+ end
131
+
132
+ # @param number [Numeric, RubyUnits::Unit]
133
+ # @param base [Numeric]
134
+ # @return [Numeric]
135
+ def log(number, base = ::Math::E)
136
+ if number.is_a?(RubyUnits::Unit)
137
+ super(number.to_f, base)
138
+ else
139
+ super
140
+ end
119
141
  end
120
142
  end
121
- # @return [Numeric]
122
- module_function :unit_atan2
123
- # @return [Numeric]
124
- module_function :atan2
143
+ end
144
+
145
+ # @see https://github.com/lsegal/yard/issues/1353
146
+ module Math
147
+ singleton_class.prepend(RubyUnits::Math)
125
148
  end
@@ -1,6 +1,3 @@
1
-
2
- $LOAD_PATH << File.dirname(__FILE__)
3
-
4
1
  # require_relative this file to avoid creating an class alias from Unit to RubyUnits::Unit
5
2
  require_relative 'version'
6
3
  require_relative 'configuration'
@@ -1,7 +1,23 @@
1
- class Numeric
2
- # make a unitless unit with a given scalar
3
- # @return (see RubyUnits::Unit#initialize)
4
- def to_unit(other = nil)
5
- other ? RubyUnits::Unit.new(self, other) : RubyUnits::Unit.new(self)
1
+ module RubyUnits
2
+ # Extra methods for [::Numeric] to allow it to be used as a [RubyUnits::Unit]
3
+ module Numeric
4
+ # Make a unitless unit with a given scalar.
5
+ # > In ruby-units <= 2.3.2 this method would create a new [RubyUnits::Unit]
6
+ # > with the scalar and passed in units. This was changed to be more
7
+ # > consistent with the behavior of [#to_unit]. Specifically the argument is
8
+ # > used as a convenience method to convert the unitless scalar unit to a
9
+ # > compatible unitless unit.
10
+ #
11
+ # @param other [RubyUnits::Unit, String] convert to same units as passed
12
+ # @return [RubyUnits::Unit]
13
+ def to_unit(other = nil)
14
+ other ? RubyUnits::Unit.new(self).convert_to(other) : RubyUnits::Unit.new(self)
15
+ end
6
16
  end
7
17
  end
18
+
19
+ # @note Do this instead of Numeric.prepend(RubyUnits::Numeric) to avoid YARD warnings
20
+ # @see https://github.com/lsegal/yard/issues/1353
21
+ class Numeric
22
+ prepend(RubyUnits::Numeric)
23
+ end
@@ -1,27 +1,40 @@
1
1
  require 'time'
2
- class String
3
- # make a string into a unit
4
- # @return (see RubyUnits::Unit#initialize)
5
- def to_unit(other = nil)
6
- other ? RubyUnits::Unit.new(self).convert_to(other) : RubyUnits::Unit.new(self)
7
- end
8
2
 
9
- alias original_format %
10
- # format unit output using formating codes
11
- # @example '%0.2f' % '1 mm'.to_unit => '1.00 mm'
12
- # @return [String]
13
- def format_with_unit(*other)
14
- if other.first.is_a?(RubyUnits::Unit)
15
- other.first.to_s(self)
16
- else
17
- original_format(*other)
3
+ module RubyUnits
4
+ # Extra methods for converting [String] objects to [RubyUnits::Unit] objects
5
+ # and using string formatting with Units.
6
+ module String
7
+ # Make a string into a unit
8
+ #
9
+ # @param other [RubyUnits::Unit, String] unit to convert to
10
+ # @return [RubyUnits::Unit]
11
+ def to_unit(other = nil)
12
+ other ? RubyUnits::Unit.new(self).convert_to(other) : RubyUnits::Unit.new(self)
13
+ end
14
+
15
+ # Format unit output using formatting codes
16
+ # @example '%0.2f' % '1 mm'.to_unit => '1.00 mm'
17
+ #
18
+ # @param other [RubyUnits::Unit, Object]
19
+ # @return [String]
20
+ def %(*other)
21
+ if other.first.is_a?(RubyUnits::Unit)
22
+ other.first.to_s(self)
23
+ else
24
+ super
25
+ end
18
26
  end
19
- end
20
- alias % format_with_unit
21
27
 
22
- # @param (see RubyUnits::Unit#convert_to)
23
- # @return (see RubyUnits::Unit#convert_to)
24
- def convert_to(other)
25
- to_unit.convert_to(other)
28
+ # @param (see RubyUnits::Unit#convert_to)
29
+ # @return (see RubyUnits::Unit#convert_to)
30
+ def convert_to(other)
31
+ to_unit.convert_to(other)
32
+ end
26
33
  end
27
34
  end
35
+
36
+ # @note Do this instead of String.prepend(RubyUnits::String) to avoid YARD warnings
37
+ # @see https://github.com/lsegal/yard/issues/1353
38
+ class String
39
+ prepend(RubyUnits::String)
40
+ end
@@ -1,82 +1,89 @@
1
1
  require 'time'
2
- #
3
- # Time math is handled slightly differently. The difference is considered to be an exact duration if
4
- # the subtracted value is in hours, minutes, or seconds. It is rounded to the nearest day if the offset
5
- # is in years, decades, or centuries. This leads to less precise values, but ones that match the
6
- # calendar better.
7
- class Time
8
- class << self
9
- alias unit_time_at at
10
- end
11
2
 
12
- # Convert a duration to a Time value by considering the duration to be the number of seconds since the
13
- # epoch
14
- # @param [Time] arg
15
- # @param [Integer] ms
16
- # @return [RubyUnits::Unit, Time]
17
- def self.at(arg, ms = nil)
18
- case arg
19
- when Time
20
- unit_time_at(arg)
21
- when RubyUnits::Unit
22
- if ms
23
- unit_time_at(arg.convert_to('s').scalar, ms)
24
- else
25
- unit_time_at(arg.convert_to('s').scalar)
3
+ module RubyUnits
4
+ # Time math is handled slightly differently. The difference is considered to be an exact duration if
5
+ # the subtracted value is in hours, minutes, or seconds. It is rounded to the nearest day if the offset
6
+ # is in years, decades, or centuries. This leads to less precise values, but ones that match the
7
+ # calendar better.
8
+ module Time
9
+ # Class methods for [Time] objects
10
+ module ClassMethods
11
+ # Convert a duration to a [::Time] object by considering the duration to be
12
+ # the number of seconds since the epoch
13
+ #
14
+ # @param [Array<RubyUnits::Unit, Numeric, Symbol, Hash>] args
15
+ # @return [::Time]
16
+ def at(*args, **kwargs)
17
+ case args.first
18
+ when RubyUnits::Unit
19
+ options = args.last.is_a?(Hash) ? args.pop : kwargs
20
+ secondary_unit = args[2] || 'microsecond'
21
+ case args[1]
22
+ when Numeric
23
+ super((args.first + RubyUnits::Unit.new(args[1], secondary_unit.to_s)).convert_to('second').scalar, **options)
24
+ else
25
+ super(args.first.convert_to('second').scalar, **options)
26
+ end
27
+ else
28
+ super(*args, **kwargs)
29
+ end
26
30
  end
27
- else
28
- ms.nil? ? unit_time_at(arg) : unit_time_at(arg, ms)
29
- end
30
- end
31
31
 
32
- # @return (see RubyUnits::Unit#initialize)
33
- def to_unit(other = nil)
34
- other ? RubyUnits::Unit.new(self).convert_to(other) : RubyUnits::Unit.new(self)
35
- end
36
-
37
- unless Time.public_method_defined?(:to_date)
38
- # :nocov_19:
39
- public :to_date
40
- # :nocov_19:
41
- end
42
-
43
- alias unit_add +
44
- # @return [RubyUnits::Unit, Time]
45
- def +(other)
46
- case other
47
- when RubyUnits::Unit
48
- other = other.convert_to('d').round.convert_to('s') if %w[y decade century].include? other.units
49
- begin
50
- unit_add(other.convert_to('s').scalar)
51
- rescue RangeError
52
- to_datetime + other
32
+ # @example
33
+ # Time.in '5 min'
34
+ # @param duration [#to_unit]
35
+ # @return [::Time]
36
+ def in(duration)
37
+ ::Time.now + duration.to_unit
53
38
  end
54
- else
55
- unit_add(other)
56
39
  end
57
- end
58
40
 
59
- # @example
60
- # Time.in '5 min'
61
- # @return (see Time#+)
62
- def self.in(duration)
63
- Time.now + duration.to_unit
64
- end
41
+ # Convert a [::Time] object to a [RubyUnits::Unit] object. The time is
42
+ # considered to be a duration with the number of seconds since the epoch.
43
+ #
44
+ # @param other [String, RubyUnits::Unit]
45
+ # @return [RubyUnits::Unit]
46
+ def to_unit(other = nil)
47
+ other ? RubyUnits::Unit.new(self).convert_to(other) : RubyUnits::Unit.new(self)
48
+ end
65
49
 
66
- alias unit_sub -
50
+ # @param other [::Time, RubyUnits::Unit]
51
+ # @return [RubyUnits::Unit, ::Time]
52
+ def +(other)
53
+ case other
54
+ when RubyUnits::Unit
55
+ other = other.convert_to('d').round.convert_to('s') if %w[y decade century].include? other.units
56
+ begin
57
+ super(other.convert_to('s').scalar)
58
+ rescue RangeError
59
+ to_datetime + other
60
+ end
61
+ else
62
+ super
63
+ end
64
+ end
67
65
 
68
- # @return [RubyUnits::Unit, Time]
69
- def -(other)
70
- case other
71
- when RubyUnits::Unit
72
- other = other.convert_to('d').round.convert_to('s') if %w[y decade century].include? other.units
73
- begin
74
- unit_sub(other.convert_to('s').scalar)
75
- rescue RangeError
76
- send(:to_datetime) - other
66
+ # @param other [::Time, RubyUnits::Unit]
67
+ # @return [RubyUnits::Unit, ::Time]
68
+ def -(other)
69
+ case other
70
+ when RubyUnits::Unit
71
+ other = other.convert_to('d').round.convert_to('s') if %w[y decade century].include? other.units
72
+ begin
73
+ super(other.convert_to('s').scalar)
74
+ rescue RangeError
75
+ public_send(:to_datetime) - other
76
+ end
77
+ else
78
+ super
77
79
  end
78
- else
79
- unit_sub(other)
80
80
  end
81
81
  end
82
82
  end
83
+
84
+ # @note Do this instead of Time.prepend(RubyUnits::Time) to avoid YARD warnings
85
+ # @see https://github.com/lsegal/yard/issues/1353
86
+ class Time
87
+ prepend(RubyUnits::Time)
88
+ singleton_class.prepend(RubyUnits::Time::ClassMethods)
89
+ end