ruby-units 2.4.1 → 4.0.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.
@@ -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,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