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.
Files changed (42) hide show
  1. data/CHANGELOG.txt +25 -7
  2. data/LICENSE.txt +1 -1
  3. data/README.md +68 -55
  4. data/RakeFile +27 -18
  5. data/TODO +2 -1
  6. data/VERSION +1 -1
  7. data/lib/ruby-units.rb +2 -2
  8. data/lib/ruby_units.rb +2 -2
  9. data/lib/ruby_units/array.rb +4 -2
  10. data/lib/ruby_units/date.rb +17 -4
  11. data/lib/ruby_units/definition.rb +100 -0
  12. data/lib/ruby_units/fixnum.rb +6 -4
  13. data/lib/ruby_units/math.rb +32 -2
  14. data/lib/ruby_units/numeric.rb +2 -1
  15. data/lib/ruby_units/object.rb +8 -1
  16. data/lib/ruby_units/string.rb +10 -109
  17. data/lib/ruby_units/string/extra.rb +45 -11
  18. data/lib/ruby_units/time.rb +11 -2
  19. data/lib/ruby_units/unit.rb +722 -434
  20. data/lib/ruby_units/unit_definitions.rb +3 -252
  21. data/lib/ruby_units/unit_definitions/base.rb +103 -0
  22. data/lib/ruby_units/unit_definitions/prefix.rb +40 -0
  23. data/lib/ruby_units/unit_definitions/standard.rb +705 -0
  24. data/lib/ruby_units/version.rb +1 -0
  25. data/ruby-units.gemspec +15 -20
  26. metadata +46 -35
  27. data/Gemfile +0 -12
  28. data/Manifest.txt +0 -19
  29. data/autotest/discover.rb +0 -1
  30. data/spec/ruby-units/array_spec.rb +0 -14
  31. data/spec/ruby-units/complex_spec.rb +0 -37
  32. data/spec/ruby-units/date_spec.rb +0 -38
  33. data/spec/ruby-units/math_spec.rb +0 -63
  34. data/spec/ruby-units/numeric_spec.rb +0 -12
  35. data/spec/ruby-units/object_spec.rb +0 -7
  36. data/spec/ruby-units/string/extra_spec.rb +0 -45
  37. data/spec/ruby-units/string_spec.rb +0 -20
  38. data/spec/ruby-units/time_spec.rb +0 -28
  39. data/spec/ruby-units/unit_spec.rb +0 -965
  40. data/spec/spec_helper.rb +0 -5
  41. data/test/test_cache.rb +0 -26
  42. 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
- 2011-10-17 1.3.2 * deprecate some string helper functions (make the gem compatible with rails)
4
- * tighten up some time helper functions so they don't make as many assumptions
5
- * time helpers no longer attempt to convert strings to time/date objects
6
- 2011-10-09 * Farads are not a base unit
7
- * CFM added to default units
8
- * multi specs run against ruby-1.9.3
9
- * internally change Unit#to to Unit#convert_to, which is the preferred form
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2006-2007 Kevin C. Olbrich
1
+ Copyright (c) 2006-2012 Kevin C. Olbrich, Ph.D.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
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.new("mm") # unit only (defaults to a value of 1)
21
- unit = Unit.new("1 mm") # create a simple unit
22
- unit = Unit.new("1 mm/s") # a compound unit
23
- unit = Unit.new("1 mm s^-1") # in exponent notation
24
- unit = Unit.new("1 kg*m^2/s^2") # complex unit
25
- unit = Unit.new("1 kg m^2 s^-2") # complex 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 = U'1 mm'
30
- unit = u'1 mm'
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 #=> true if units are compatible
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" # convert to 'feet'
69
- unit >>= "ft" # convert and overwrite original object
70
- unit3 = unit1 + unit2 # resulting object will have the units of unit1
71
- unit3 = unit1 - unit2 # resulting object will have the units of unit1
72
- unit1 <=> unit2 # does comparison on quantities in base units, throws an exception if not compatible
73
- unit1 === unit2 # true if units and quantity are the same, even if 'equivalent' by <=>
74
- unit.to('ft') # convert
75
- unit1 + unit2 >> "ft" # converts result of math to 'ft'
76
- (unit1 + unit2).convert_to('ft') # converts result 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 preferred abbreviation for the units and prefixes.
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.new('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
85
+ Unit('1.5 mm').to_s("%0.2f") # "1.50 mm". Enter any valid format
89
86
  string. Also accepts strftime format
90
- U('1.5 mm').to_s("in") # converts to inches before printing
91
- U("2 m").to_s(:ft) # returns 6'7"
92
- U("100 kg").to_s(:lbs) # returns 220 lbs, 7 oz
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".unit
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'.unit #=> 1 h
116
- '0:30'.unit #=> 0.5 h
117
- '0:30:30'.unit #=> 0.5 h + 30 sec
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
- [U('0 h')..U('10 h')].each {|x| p x}
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'.unit >> 'tempF' #=> 98.6 tempF
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'.unit + '10 degC'.unit # '110 tempC'.unit
140
- '100 tempC'.unit - '10 degC'.unit # '90 tempC'.unit
141
- '100 tempC'.unit + '50 tempC'.unit # exception
142
- '100 tempC'.unit - '50 tempC'.unit # '50 degC'.unit
143
- '50 tempC'.unit - '100 tempC'.unit # '-50 degC'.unit
144
- '100 tempC'.unit * [scalar] # '100*scalar tempC'.unit
145
- '100 tempC'.unit / [scalar] # '100/scalar tempC'.unit
146
- '100 tempC'.unit * [unit] # exception
147
- '100 tempC'.unit / [unit] # exception
148
- '100 tempC'.unit ** N # exception
149
-
150
- '100 tempC'.unit >> 'degC' #=> '100 degC'.unit
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'.unit >> 'tempC' #=> '-173 tempC'.unit
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'.unit + '100 degC'.unit #=> '100 tempC'.unit
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 probably go away completely in an upcoming release, so it would be a good idea to refactor your code
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
- ruby-1.9.3@ruby-units
88
- rbx@ruby-units
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
- ruby-1.9.3@ruby-units
102
- rbx@ruby-units
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(',')} specs"
114
+ exec "rvm #{rubies.join(',')} do rake spec"
106
115
  end
107
116
 
108
117
  task :default => :test
data/TODO CHANGED
@@ -1,2 +1,3 @@
1
1
  2006-10-02 Currency handling remains to be implemented well
2
- 2011-04-23 Refactor caching
2
+ 2011-04-23 Refactor caching
3
+ 2011-11-23 Perform all internal calculations in rational numbers to avoid round off problems
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.3.2
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'
@@ -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
@@ -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