ruby-units 1.3.2 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +25 -7
- data/LICENSE.txt +1 -1
- data/README.md +68 -55
- data/RakeFile +27 -18
- data/TODO +2 -1
- data/VERSION +1 -1
- data/lib/ruby-units.rb +2 -2
- data/lib/ruby_units.rb +2 -2
- data/lib/ruby_units/array.rb +4 -2
- data/lib/ruby_units/date.rb +17 -4
- data/lib/ruby_units/definition.rb +100 -0
- data/lib/ruby_units/fixnum.rb +6 -4
- data/lib/ruby_units/math.rb +32 -2
- data/lib/ruby_units/numeric.rb +2 -1
- data/lib/ruby_units/object.rb +8 -1
- data/lib/ruby_units/string.rb +10 -109
- data/lib/ruby_units/string/extra.rb +45 -11
- data/lib/ruby_units/time.rb +11 -2
- data/lib/ruby_units/unit.rb +722 -434
- data/lib/ruby_units/unit_definitions.rb +3 -252
- data/lib/ruby_units/unit_definitions/base.rb +103 -0
- data/lib/ruby_units/unit_definitions/prefix.rb +40 -0
- data/lib/ruby_units/unit_definitions/standard.rb +705 -0
- data/lib/ruby_units/version.rb +1 -0
- data/ruby-units.gemspec +15 -20
- metadata +46 -35
- data/Gemfile +0 -12
- data/Manifest.txt +0 -19
- data/autotest/discover.rb +0 -1
- data/spec/ruby-units/array_spec.rb +0 -14
- data/spec/ruby-units/complex_spec.rb +0 -37
- data/spec/ruby-units/date_spec.rb +0 -38
- data/spec/ruby-units/math_spec.rb +0 -63
- data/spec/ruby-units/numeric_spec.rb +0 -12
- data/spec/ruby-units/object_spec.rb +0 -7
- data/spec/ruby-units/string/extra_spec.rb +0 -45
- data/spec/ruby-units/string_spec.rb +0 -20
- data/spec/ruby-units/time_spec.rb +0 -28
- data/spec/ruby-units/unit_spec.rb +0 -965
- data/spec/spec_helper.rb +0 -5
- data/test/test_cache.rb +0 -26
- data/test/test_ruby-units.rb +0 -976
data/CHANGELOG.txt
CHANGED
@@ -1,12 +1,30 @@
|
|
1
1
|
Change Log for Ruby-units
|
2
2
|
=========================
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
2011-
|
7
|
-
|
8
|
-
|
9
|
-
|
3
|
+
2012-01-02 1.4.0 * Fix some definitions that were just wrong (amu, dalton)
|
4
|
+
* Definition uses name of unit if no aliases provided
|
5
|
+
* Refactor definition process. New units are immediately available
|
6
|
+
2011-12-31 * Define standard units in terms of base and other standard units -- more internally consistent
|
7
|
+
and less prone to round-off errors.
|
8
|
+
* add 'poundal'
|
9
|
+
* remove 'wtpercent'
|
10
|
+
2011-12-30 * Bump version
|
11
|
+
* Define compound units with base units for consistency
|
12
|
+
* distinguish between a league and a nautical league
|
13
|
+
* NOTE: the new unit definition DSL is not backwardly compatible with the old method
|
14
|
+
(which is now deprecated).
|
15
|
+
* Fix issue #27
|
16
|
+
2011-12-18 * Can define a display_name for units (fixes #26)
|
17
|
+
2011-12-04 * Documentation improvements
|
18
|
+
* Add DSL for defining/redefining units
|
19
|
+
2011-11-24 * improve yard documentation
|
20
|
+
* add 'tbsp' as an alias for tablespoon
|
21
|
+
2011-10-17 1.3.2 * deprecate some string helper functions (make the gem compatible with rails)
|
22
|
+
* tighten up some time helper functions so they don't make as many assumptions
|
23
|
+
* time helpers no longer attempt to convert strings to time/date objects
|
24
|
+
2011-10-09 * Farads are not a base unit
|
25
|
+
* CFM added to default units
|
26
|
+
* multi specs run against ruby-1.9.3
|
27
|
+
* internally change Unit#to to Unit#convert_to, which is the preferred form
|
10
28
|
|
11
29
|
2011-04-23 1.3.0.a * Some internal restructuring
|
12
30
|
* Implement specs for core behaviors
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -17,21 +17,17 @@ This package may be installed using: `gem install ruby-units`
|
|
17
17
|
|
18
18
|
## Usage:
|
19
19
|
unit = Unit.new("1") # constant only
|
20
|
-
unit = Unit
|
21
|
-
unit = Unit
|
22
|
-
unit = Unit
|
23
|
-
unit = Unit
|
24
|
-
unit = Unit
|
25
|
-
unit = Unit
|
20
|
+
unit = Unit("mm") # unit only (defaults to a scalar of 1)
|
21
|
+
unit = Unit("1 mm") # create a simple unit
|
22
|
+
unit = Unit("1 mm/s") # a compound unit
|
23
|
+
unit = Unit("1 mm s^-1") # in exponent notation
|
24
|
+
unit = Unit("1 kg*m^2/s^2") # complex unit
|
25
|
+
unit = Unit("1 kg m^2 s^-2") # complex unit
|
26
26
|
unit = Unit("1 mm") # shorthand
|
27
27
|
unit = "1 mm".to_unit # convert string object
|
28
28
|
unit = object.to_unit # convert any object using object.to_s
|
29
|
-
unit =
|
30
|
-
unit =
|
31
|
-
unit = '1 mm'.unit
|
32
|
-
unit = '1 mm'.u
|
33
|
-
unit = '1/4 cup'.unit # Rational number
|
34
|
-
unit = '1+1i mm'.unit # Complex Number
|
29
|
+
unit = Unit('1/4 cup') # Rational number
|
30
|
+
unit = Unit('1+1i mm') # Complex Number
|
35
31
|
|
36
32
|
## Rules:
|
37
33
|
1. only 1 quantity per unit (with 2 exceptions... 6'5" and '8 lbs 8 oz')
|
@@ -41,7 +37,8 @@ This package may be installed using: `gem install ruby-units`
|
|
41
37
|
## Unit compatability:
|
42
38
|
Many methods require that the units of two operands are compatible. Compatible units are those that can be easily converted into each other, such as 'meters' and 'feet'.
|
43
39
|
|
44
|
-
unit1 =~ unit2
|
40
|
+
unit1 =~ unit2 #=> true if units are compatible
|
41
|
+
unit1.compatible?(unit2) #=> true if units are compatible
|
45
42
|
|
46
43
|
## Unit Math:
|
47
44
|
Unit#+() # Add. only works if units are compatible
|
@@ -65,61 +62,54 @@ This will work as expected so long as you start the formula with a Unit object.
|
|
65
62
|
## Conversions & comparisons
|
66
63
|
Units can be converted to other units in a couple of ways.
|
67
64
|
|
68
|
-
unit1 = unit >> "ft"
|
69
|
-
unit >>= "ft"
|
70
|
-
unit3 = unit1 + unit2
|
71
|
-
unit3 = unit1 - unit2
|
72
|
-
unit1 <=> unit2
|
73
|
-
unit1 === unit2
|
74
|
-
unit.
|
75
|
-
unit1 + unit2 >> "ft"
|
76
|
-
(unit1 + unit2).convert_to('ft')
|
65
|
+
unit1 = unit >> "ft" # convert to 'feet'
|
66
|
+
unit >>= "ft" # convert and overwrite original object
|
67
|
+
unit3 = unit1 + unit2 # resulting object will have the units of unit1
|
68
|
+
unit3 = unit1 - unit2 # resulting object will have the units of unit1
|
69
|
+
unit1 <=> unit2 # does comparison on quantities in base units, throws an exception if not compatible
|
70
|
+
unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=>
|
71
|
+
unit.convert_to('ft') # convert
|
72
|
+
unit1 + unit2 >> "ft" # converts result of math to 'ft'
|
73
|
+
(unit1 + unit2).convert_to('ft') # converts result to 'ft'
|
77
74
|
|
78
75
|
Any object that defines a 'to_unit' method will be automatically coerced to a unit during calculations.
|
79
76
|
|
80
77
|
## Text Output
|
81
|
-
Units will display themselves nicely based on the
|
78
|
+
Units will display themselves nicely based on the display_name for the units and prefixes.
|
82
79
|
Since Unit implements a Unit#to_s, all that is needed in most cases is:
|
83
80
|
|
84
81
|
"#{Unit('1 mm')}" #=> "1 mm"
|
85
82
|
|
86
83
|
The to_s also accepts some options.
|
87
84
|
|
88
|
-
Unit
|
85
|
+
Unit('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
|
89
86
|
string. Also accepts strftime format
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
87
|
+
Unit('1.5 mm').to_s("in") # converts to inches before printing
|
88
|
+
Unit("2 m").to_s(:ft) # returns 6'7"
|
89
|
+
Unit("100 kg").to_s(:lbs) # returns 220 lbs, 7 oz
|
90
|
+
|
94
91
|
|
95
92
|
## Time Helpers
|
96
93
|
Time, Date, and DateTime objects can have time units added or subtracted.
|
97
94
|
|
98
|
-
Time.now + "10 min"
|
95
|
+
Time.now + Unit("10 min")
|
99
96
|
|
100
97
|
Several helpers have also been defined.
|
101
98
|
Note: If you include the 'Chronic' gem, you can specify times in natural
|
102
99
|
language.
|
103
100
|
|
104
101
|
Unit('min').since(DateTime.parse('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
102
|
|
113
103
|
Durations may be entered as 'HH:MM:SS, usec' and will be returned in 'hours'.
|
114
104
|
|
115
|
-
'1:00'
|
116
|
-
'0:30'
|
117
|
-
'0:30:30'
|
105
|
+
Unit('1:00') #=> 1 h
|
106
|
+
Unit('0:30') #=> 0.5 h
|
107
|
+
Unit('0:30:30') #=> 0.5 h + 30 sec
|
118
108
|
|
119
109
|
If only one ":" is present, it is interpreted as the separator between hours and minutes.
|
120
110
|
|
121
111
|
## Ranges
|
122
|
-
[
|
112
|
+
[Unit('0 h')..Unit('10 h')].each {|x| p x}
|
123
113
|
works so long as the starting point has an integer scalar
|
124
114
|
|
125
115
|
## Math functions
|
@@ -130,29 +120,52 @@ Ruby-units makes a distinction between a temperature (which technically is a pro
|
|
130
120
|
|
131
121
|
Temperature units (i.e., 'tempK') can be converted back and forth, and will take into account the differences in the zero points of the various scales. Differential temperature (e.g., '100 degC'.unit) units behave like most other units.
|
132
122
|
|
133
|
-
'37 tempC'.
|
123
|
+
Unit('37 tempC').convert_to('tempF') #=> 98.6 tempF
|
134
124
|
|
135
125
|
Ruby-units will raise an exception if you attempt to create a temperature unit that would fall below absolute zero.
|
136
126
|
|
137
127
|
Unit math on temperatures is fairly limited.
|
138
128
|
|
139
|
-
'100 tempC'
|
140
|
-
'100 tempC'
|
141
|
-
'100 tempC'
|
142
|
-
'100 tempC'
|
143
|
-
'50 tempC'
|
144
|
-
'100 tempC'
|
145
|
-
'100 tempC'
|
146
|
-
'100 tempC'
|
147
|
-
'100 tempC'
|
148
|
-
'100 tempC'
|
149
|
-
|
150
|
-
'100 tempC'.
|
129
|
+
Unit('100 tempC') + Unit('10 degC') # '110 tempC'.unit
|
130
|
+
Unit('100 tempC') - Unit('10 degC') # '90 tempC'.unit
|
131
|
+
Unit('100 tempC') + Unit('50 tempC') # exception
|
132
|
+
Unit('100 tempC') - Unit('50 tempC') # '50 degC'.unit
|
133
|
+
Unit('50 tempC') - Unit('100 tempC') # '-50 degC'.unit
|
134
|
+
Unit('100 tempC') * [scalar] # '100*scalar tempC'.unit
|
135
|
+
Unit('100 tempC') / [scalar] # '100/scalar tempC'.unit
|
136
|
+
Unit('100 tempC') * [unit] # exception
|
137
|
+
Unit('100 tempC') / [unit] # exception
|
138
|
+
Unit('100 tempC') ** N # exception
|
139
|
+
|
140
|
+
Unit('100 tempC').convert_to('degC') #=> Unit('100 degC')
|
151
141
|
This conversion references the 0 point on the scale of the temperature unit
|
152
142
|
|
153
|
-
'100 degC'.
|
143
|
+
Unit('100 degC').convert_to('tempC') #=> '-173 tempC'.unit
|
154
144
|
These conversions are always interpreted as being relative to absolute zero.
|
155
145
|
Conversions are probably better done like this...
|
156
146
|
|
157
|
-
'0 tempC'
|
147
|
+
Unit('0 tempC') + Unit('100 degC') #=> Unit('100 tempC')
|
148
|
+
|
149
|
+
## Defininig Units
|
150
|
+
|
151
|
+
It is possible to define new units or redefine existing ones.
|
152
|
+
|
153
|
+
### Define New Unit
|
154
|
+
|
155
|
+
The easiest approach is to define a unit in terms of other units.
|
156
|
+
|
157
|
+
Unit.define("foobar") do |foobar|
|
158
|
+
foobar.definition = Unit("1 foo") * Unit("1 bar") # anything that results in a Unit object
|
159
|
+
foobar.aliases = %w{foobar fb} # array of synonyms for the unit
|
160
|
+
foobar.display_name = "Foobar" # How unit is displayed when output
|
161
|
+
end
|
162
|
+
|
163
|
+
### Redefine Existing Unit
|
164
|
+
|
165
|
+
Redefining a unit allows the user to change a single aspect of a definition without having to re-create the entire definition.
|
166
|
+
This is useful for changing display names, adding aliases, etc.
|
158
167
|
|
168
|
+
Unit.redefine!("cup") do |cup|
|
169
|
+
cup.display_name = "cup"
|
170
|
+
end
|
171
|
+
|
data/RakeFile
CHANGED
@@ -12,7 +12,8 @@ begin
|
|
12
12
|
gem.authors = ["Kevin Olbrich, Ph.D."]
|
13
13
|
gem.email = ["kevin.olbrich+ruby_units@gmail.com"]
|
14
14
|
gem.homepage = "https://github.com/olbrich/ruby-units"
|
15
|
-
gem.files.exclude(".*")
|
15
|
+
gem.files.exclude(".*","test/**/*","spec/**/*","autotest/**/*", "Gemfile")
|
16
|
+
gem.license = "MIT"
|
16
17
|
gem.post_install_message = <<-EOS
|
17
18
|
====================
|
18
19
|
Deprecation Warning
|
@@ -31,7 +32,7 @@ The extra functions mostly work the same, but will no longer properly handle cas
|
|
31
32
|
|
32
33
|
Pass in a Date, Time, or DateTime object to get the expected result.
|
33
34
|
|
34
|
-
They will
|
35
|
+
They will go away completely in the next release, so it would be a good idea to refactor your code
|
35
36
|
to avoid using them. They will also throw deprecation warnings when they are used.
|
36
37
|
EOS
|
37
38
|
end
|
@@ -50,6 +51,16 @@ begin
|
|
50
51
|
rescue LoadError
|
51
52
|
end
|
52
53
|
|
54
|
+
begin
|
55
|
+
require 'simplecov'
|
56
|
+
desc "code coverage report using simplecov (ruby 1.9+)"
|
57
|
+
task :simplecov do
|
58
|
+
ENV['COVERAGE']='true'
|
59
|
+
Rake::Task['spec'].invoke
|
60
|
+
end
|
61
|
+
rescue LoadError
|
62
|
+
end
|
63
|
+
|
53
64
|
begin
|
54
65
|
require 'rspec/core/rake_task'
|
55
66
|
|
@@ -80,29 +91,27 @@ task :specs => :spec
|
|
80
91
|
desc "Run tests against several ruby versions, requires rvm"
|
81
92
|
task :multitest do
|
82
93
|
rubies = %w{
|
83
|
-
ruby-1.8.7@ruby-units
|
84
|
-
ruby-1.8.7@ruby-units-with-chronic
|
85
|
-
ruby-1.9.2@ruby-units
|
86
|
-
ruby-1.9.2@ruby-units-with-chronic
|
87
|
-
|
88
|
-
|
89
|
-
jruby-1.6.4@ruby-units
|
94
|
+
ruby-1.8.7-p352@ruby-units
|
95
|
+
ruby-1.8.7-p352@ruby-units-with-chronic
|
96
|
+
ruby-1.9.2-p290@ruby-units
|
97
|
+
ruby-1.9.2-p290@ruby-units-with-chronic
|
98
|
+
rbx-head@ruby-units
|
99
|
+
jruby-1.6.5@ruby-units
|
90
100
|
}
|
91
|
-
exec "rvm #{rubies.join(',')} tests"
|
101
|
+
exec "rvm #{rubies.join(',')} do rake tests"
|
92
102
|
end
|
93
103
|
|
94
104
|
desc "Run specs against several ruby versions, requires rvm"
|
95
105
|
task :multispec do
|
96
106
|
rubies = %w{
|
97
|
-
ruby-1.8.7@ruby-units
|
98
|
-
ruby-1.8.7@ruby-units-with-chronic
|
99
|
-
ruby-1.9.2@ruby-units
|
100
|
-
ruby-1.9.2@ruby-units-with-chronic
|
101
|
-
|
102
|
-
|
103
|
-
jruby-1.6.4@ruby-units
|
107
|
+
ruby-1.8.7-p352@ruby-units
|
108
|
+
ruby-1.8.7-p352@ruby-units-with-chronic
|
109
|
+
ruby-1.9.2-p290@ruby-units
|
110
|
+
ruby-1.9.2-p290@ruby-units-with-chronic
|
111
|
+
rbx-head@ruby-units
|
112
|
+
jruby-1.6.5@ruby-units
|
104
113
|
}
|
105
|
-
exec "rvm #{rubies.join(',')}
|
114
|
+
exec "rvm #{rubies.join(',')} do rake spec"
|
106
115
|
end
|
107
116
|
|
108
117
|
task :default => :test
|
data/TODO
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.
|
1
|
+
1.4.0
|
data/lib/ruby-units.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__)
|
2
2
|
require "ruby_units/version"
|
3
|
+
require "ruby_units/definition"
|
3
4
|
require "ruby_units/cache"
|
4
5
|
require 'ruby_units/array'
|
5
6
|
require 'ruby_units/date'
|
@@ -8,7 +9,6 @@ require 'ruby_units/math'
|
|
8
9
|
require 'ruby_units/numeric'
|
9
10
|
require 'ruby_units/object'
|
10
11
|
require 'ruby_units/string'
|
11
|
-
require 'ruby_units/unit_definitions'
|
12
12
|
require 'ruby_units/unit'
|
13
13
|
require 'ruby_units/fixnum'
|
14
|
-
|
14
|
+
require 'ruby_units/unit_definitions'
|
data/lib/ruby_units.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
$LOAD_PATH << File.dirname(__FILE__)
|
2
2
|
require "ruby_units/version"
|
3
|
+
require "ruby_units/definition"
|
3
4
|
require "ruby_units/cache"
|
4
5
|
require 'ruby_units/array'
|
5
6
|
require 'ruby_units/date'
|
@@ -8,7 +9,6 @@ require 'ruby_units/math'
|
|
8
9
|
require 'ruby_units/numeric'
|
9
10
|
require 'ruby_units/object'
|
10
11
|
require 'ruby_units/string'
|
11
|
-
require 'ruby_units/unit_definitions'
|
12
12
|
require 'ruby_units/unit'
|
13
13
|
require 'ruby_units/fixnum'
|
14
|
-
|
14
|
+
require 'ruby_units/unit_definitions'
|
data/lib/ruby_units/array.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
|
-
# make a unit from an array
|
2
|
-
# [1, 'mm'].unit => 1 mm
|
3
1
|
class Array
|
2
|
+
# Construct a unit from an array
|
3
|
+
# @example [1, 'mm'].to_unit => Unit("1 mm")
|
4
|
+
# @return (see Unit#initialize)
|
5
|
+
# @param [Object] other convert to same units as passed
|
4
6
|
def to_unit(other = nil)
|
5
7
|
other ? Unit.new(self).convert_to(other) : Unit.new(self)
|
6
8
|
end
|
data/lib/ruby_units/date.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
-
# Allow date objects to do offsets by a time unit
|
2
|
-
# Date.today + U"1 week" => gives today+1 week
|
3
|
-
|
4
1
|
require 'date'
|
5
2
|
|
3
|
+
# Allow date objects to do offsets by a time unit
|
4
|
+
# Date.today + U"1 week" => gives today+1 week
|
6
5
|
class Date
|
7
6
|
alias :unit_date_add :+
|
7
|
+
# @param [Object] unit
|
8
|
+
# @return [Unit]
|
8
9
|
def +(unit)
|
9
10
|
case unit
|
10
11
|
when Unit
|
@@ -14,9 +15,10 @@ class Date
|
|
14
15
|
unit_date_add(unit)
|
15
16
|
end
|
16
17
|
end
|
17
|
-
|
18
18
|
|
19
19
|
alias :unit_date_sub :-
|
20
|
+
# @param [Object] unit
|
21
|
+
# @return [Unit]
|
20
22
|
def -(unit)
|
21
23
|
case unit
|
22
24
|
when Unit
|
@@ -27,27 +29,38 @@ class Date
|
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
32
|
+
# Construct a unit from a Date
|
33
|
+
# @example Date.today.to_unit => Unit
|
34
|
+
# @return (see Unit#initialize)
|
35
|
+
# @param [Object] other convert to same units as passed
|
30
36
|
def to_unit(other = nil)
|
31
37
|
other ? Unit.new(self).convert_to(other) : Unit.new(self)
|
32
38
|
end
|
33
39
|
alias :unit :to_unit
|
34
40
|
|
41
|
+
# :nocov_19:
|
35
42
|
unless Date.instance_methods.include?(:to_time)
|
43
|
+
# @return [Time]
|
36
44
|
def to_time
|
37
45
|
Time.local(*ParseDate.parsedate(self.to_s))
|
38
46
|
end
|
39
47
|
end
|
48
|
+
# :nocov_19:
|
40
49
|
|
41
50
|
alias :units_datetime_inspect :inspect
|
51
|
+
# @deprecated
|
42
52
|
def inspect(raw = false)
|
43
53
|
return self.units_datetime_inspect if raw
|
44
54
|
self.to_s
|
45
55
|
end
|
46
56
|
|
47
57
|
unless Date.instance_methods.include?(:to_date)
|
58
|
+
# :nocov_19:
|
59
|
+
# @return [Date]
|
48
60
|
def to_date
|
49
61
|
Date.civil(self.year, self.month, self.day)
|
50
62
|
end
|
63
|
+
# :nocov_19:
|
51
64
|
end
|
52
65
|
|
53
66
|
end
|
@@ -0,0 +1,100 @@
|
|
1
|
+
class Unit < Numeric
|
2
|
+
|
3
|
+
# Handle the definition of units
|
4
|
+
class Definition
|
5
|
+
|
6
|
+
# @return [Array]
|
7
|
+
attr_writer :aliases
|
8
|
+
|
9
|
+
# @return [Symbol]
|
10
|
+
attr_accessor :kind
|
11
|
+
|
12
|
+
# @return [Numeric]
|
13
|
+
attr_accessor :scalar
|
14
|
+
|
15
|
+
# @return [Array]
|
16
|
+
attr_accessor :numerator
|
17
|
+
|
18
|
+
# @return [Array]
|
19
|
+
attr_accessor :denominator
|
20
|
+
|
21
|
+
# @return [String]
|
22
|
+
attr_accessor :display_name
|
23
|
+
|
24
|
+
# @example Raw definition from a hash
|
25
|
+
# Unit::Definition.new("rack-unit",[%w{U rack-U}, (6405920109971793/144115188075855872), :length, %w{<meter>} ])
|
26
|
+
#
|
27
|
+
# @example Block form
|
28
|
+
# Unit::Definition.new("rack-unit") do |unit|
|
29
|
+
# unit.aliases = %w{U rack-U}
|
30
|
+
# unit.definition = Unit("7/4 inches")
|
31
|
+
# end
|
32
|
+
#
|
33
|
+
def initialize(_name, _definition = [], &block)
|
34
|
+
yield self if block_given?
|
35
|
+
self.name ||= _name.gsub(/[<>]/,'')
|
36
|
+
@aliases ||= (_definition[0] || [_name])
|
37
|
+
@scalar ||= _definition[1]
|
38
|
+
@kind ||= _definition[2]
|
39
|
+
@numerator ||= _definition[3] || Unit::UNITY_ARRAY
|
40
|
+
@denominator ||= _definition[4] || Unit::UNITY_ARRAY
|
41
|
+
@display_name ||= @aliases.first
|
42
|
+
end
|
43
|
+
|
44
|
+
# name of the unit
|
45
|
+
# nil if name is not set, adds '<' and '>' around the name
|
46
|
+
# @return [String, nil]
|
47
|
+
# @todo refactor Unit and Unit::Definition so we don't need to wrap units with angle brackets
|
48
|
+
def name
|
49
|
+
"<#{@name}>" if (defined?(@name) && @name)
|
50
|
+
end
|
51
|
+
|
52
|
+
# set the name, strip off '<' and '>'
|
53
|
+
# @param [String]
|
54
|
+
# @return [String]
|
55
|
+
def name=(_name)
|
56
|
+
@name = _name.gsub(/[<>]/,'')
|
57
|
+
end
|
58
|
+
|
59
|
+
# alias array must contain the name of the unit and entries must be unique
|
60
|
+
# @return [Array]
|
61
|
+
def aliases
|
62
|
+
[[@aliases], @name].flatten.compact.uniq
|
63
|
+
end
|
64
|
+
|
65
|
+
# define a unit in terms of another unit
|
66
|
+
# @param [Unit] unit
|
67
|
+
# @return [Unit::Definition]
|
68
|
+
def definition=(unit)
|
69
|
+
_base = unit.to_base
|
70
|
+
@scalar = _base.scalar
|
71
|
+
@kind = _base.kind
|
72
|
+
@numerator = _base.numerator
|
73
|
+
@denominator = _base.denominator
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
# is this definition for a prefix?
|
78
|
+
# @return [Boolean]
|
79
|
+
def prefix?
|
80
|
+
self.kind == :prefix
|
81
|
+
end
|
82
|
+
|
83
|
+
# Is this definition the unity definition?
|
84
|
+
# @return [Boolean]
|
85
|
+
def unity?
|
86
|
+
self.prefix? && self.scalar == 1
|
87
|
+
end
|
88
|
+
|
89
|
+
# is this a base unit?
|
90
|
+
# units are base units if the scalar is one, and the unit is defined in terms of itself.
|
91
|
+
# @return [Boolean]
|
92
|
+
def base?
|
93
|
+
(self.denominator == Unit::UNITY_ARRAY) &&
|
94
|
+
(self.numerator != Unit::UNITY_ARRAY) &&
|
95
|
+
(self.numerator.size == 1) &&
|
96
|
+
(self.scalar == 1) &&
|
97
|
+
(self.numerator.first == self.name)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|