quantify 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,19 @@
1
+
2
+ class Numeric
3
+ # Syntactic sugar for defining instances of the Quantity class.
4
+ #
5
+ # Enables quantities to be specified by using unit names, symbols or JScience
6
+ # labels as argments on Numeric objects, e.g.
7
+ #
8
+ # 1.5.metre is equivalent to Quantity. new 1.5, :metre
9
+ #
10
+ # 1000.t is equivalent to Quantity. new 1000, :t
11
+ #
12
+ def method_missing(method, *args, &block)
13
+ if unit = Unit.for(method.to_s)
14
+ Quantify::Quantity.new self, unit
15
+ else
16
+ super
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,29 @@
1
+
2
+ class String
3
+
4
+ def with_superscript_characters
5
+ self.gsub(/\^2\b/,"²").gsub(/\^3\b/,"³")
6
+ end
7
+
8
+ def without_superscript_characters
9
+ self.gsub(/¹\b/,"").gsub(/²\b/,"^2").gsub(/³\b/,"^3")
10
+ end
11
+
12
+ def remove_underscores
13
+ self.gsub("_"," ")
14
+ end
15
+
16
+ def words
17
+ split(/\s+/)
18
+ end
19
+
20
+ def word_count
21
+ words.size
22
+ end
23
+
24
+ def to_quantity
25
+ Quantify::Quantity.parse(self)
26
+ end
27
+ alias :to_q :to_quantity
28
+
29
+ end
@@ -0,0 +1,7 @@
1
+ class Symbol
2
+
3
+ def remove_underscores
4
+ self.to_s.remove_underscores
5
+ end
6
+
7
+ end
@@ -1,4 +1,3 @@
1
- #! usr/bin/ruby
2
1
 
3
2
  module Quantify
4
3
 
@@ -52,7 +51,7 @@ module Quantify
52
51
  #
53
52
  def self.base_dimensions
54
53
  @@dimensions.select do |dimensions|
55
- BASE_QUANTITIES.map(&:standardize).include? dimensions.describe
54
+ BASE_QUANTITIES.map {|q| q.remove_underscores}.include?(dimensions.describe)
56
55
  end
57
56
  end
58
57
 
@@ -83,8 +82,8 @@ module Quantify
83
82
  # Remove a dimension from the system of known dimensions
84
83
  def self.unload(*unloaded_dimensions)
85
84
  [unloaded_dimensions].flatten.each do |unloaded_dimension|
86
- unloaded_dimension = Dimensions.for(unloaded_dimensions)
87
- @@dimensions.delete_if { |unit| unit.physical_quantity == unloaded_dimension.physical_quantity }
85
+ unloaded_dimension = Dimensions.for(unloaded_dimension)
86
+ @@dimensions.delete_if { |dimension| dimension.has_same_identity_as? unloaded_dimension }
88
87
  end
89
88
  end
90
89
 
@@ -97,7 +96,7 @@ module Quantify
97
96
  # ... ]
98
97
  #
99
98
  def self.physical_quantities
100
- @@dimensions.map(&:physical_quantity)
99
+ @@dimensions.map {|dimension| dimension.physical_quantity }
101
100
  end
102
101
 
103
102
  # Retrieve a known quantity - returns a Dimensions instance, which is a
@@ -116,10 +115,9 @@ module Quantify
116
115
  #
117
116
  def self.for(name)
118
117
  return name if name.is_a? Dimensions
119
- if name.is_a? String or name.is_a? Symbol
120
- if quantity = @@dimensions.find do |quantity|
121
- quantity.physical_quantity == name.standardize.downcase
122
- end
118
+ if (name.is_a?(String) || name.is_a?(Symbol))
119
+ name = name.remove_underscores.downcase
120
+ if quantity = @@dimensions.find { |quantity| quantity.physical_quantity == name }
123
121
  return quantity.clone
124
122
  else
125
123
  raise Exceptions::InvalidArgumentError, "Physical quantity not known: #{name}"
@@ -141,8 +139,8 @@ module Quantify
141
139
  #
142
140
  # end
143
141
  #
144
- def self.configure &block
145
- self.class_eval &block if block
142
+ def self.configure(&block)
143
+ self.class_eval(&block) if block
146
144
  end
147
145
 
148
146
  # Provides a shorthand for retrieving known quantities, e.g.:
@@ -185,7 +183,7 @@ module Quantify
185
183
  #
186
184
  def initialize(options={})
187
185
  if options.has_key?(:physical_quantity)
188
- @physical_quantity = options.delete(:physical_quantity).standardize.downcase
186
+ @physical_quantity = options.delete(:physical_quantity).remove_underscores.downcase
189
187
  end
190
188
  enumerate_base_quantities(options)
191
189
  describe
@@ -199,7 +197,7 @@ module Quantify
199
197
  # description of the physical quantity represented.
200
198
  #
201
199
  def load
202
- if describe and not loaded?
200
+ if describe && !loaded?
203
201
  @@dimensions << self
204
202
  elsif describe
205
203
  raise Exceptions::InvalidDimensionError, "A dimension instance with the same physical quantity already exists"
@@ -218,7 +216,7 @@ module Quantify
218
216
  end
219
217
 
220
218
  def has_same_identity_as?(other)
221
- self.physical_quantity == other.physical_quantity and not self.physical_quantity.nil?
219
+ @physical_quantity == other.physical_quantity && !@physical_quantity.nil?
222
220
  end
223
221
 
224
222
  # Return a description of what physical quantity self represents. If no
@@ -246,7 +244,7 @@ module Quantify
246
244
  #
247
245
  def get_description
248
246
  similar = @@dimensions.find { |quantity| quantity == self }
249
- @physical_quantity = ( similar.nil? ? nil : similar.physical_quantity )
247
+ @physical_quantity = similar.nil? ? nil : similar.physical_quantity
250
248
  end
251
249
 
252
250
  # Returns an array containing the known units which represent the physical
@@ -287,8 +285,8 @@ module Quantify
287
285
  # #=> 'metre squared per second'
288
286
  #
289
287
  def si_unit
290
- return Unit.steridian if self.describe == 'solid angle'
291
- return Unit.radian if self.describe == 'plane angle'
288
+ return Unit.steridian if describe == 'solid angle'
289
+ return Unit.radian if describe == 'plane angle'
292
290
  return si_base_units.inject(Unit.unity) do |compound,unit|
293
291
  compound * unit
294
292
  end.or_equivalent
@@ -319,7 +317,7 @@ module Quantify
319
317
  def si_base_units(by=nil)
320
318
  self.to_hash.map do |dimension,index|
321
319
  Unit.base_quantity_si_units.select do |unit|
322
- unit.measures == dimension.standardize
320
+ unit.measures == dimension.remove_underscores
323
321
  end.first.clone ** index
324
322
  end.map(&by)
325
323
  end
@@ -346,7 +344,7 @@ module Quantify
346
344
  # Returns true if self represents one of the base quantities (i.e. length,
347
345
  # mass, time, etc.)
348
346
  def is_base?
349
- base_quantities.size == 1 and
347
+ base_quantities.size == 1 &&
350
348
  self.instance_variable_get(base_quantities.first) == 1 ? true : false
351
349
  end
352
350
 
@@ -495,7 +493,7 @@ module Quantify
495
493
  def enumerate_base_quantities(options)
496
494
  options.each_pair do |base_quantity,index|
497
495
  base_quantity = base_quantity.to_s.downcase.to_sym
498
- unless index.is_a? Integer and BASE_QUANTITIES.include? base_quantity
496
+ unless index.is_a?(Integer) && BASE_QUANTITIES.include?(base_quantity)
499
497
  raise Exceptions::InvalidDimensionError, "An invalid base quantity was specified (#{base_quantity})"
500
498
  end
501
499
  variable = "@#{base_quantity}"
@@ -514,7 +512,7 @@ module Quantify
514
512
 
515
513
  # Make object represent a dimensionless quantity.
516
514
  def make_dimensionless
517
- self.physical_quantity = 'dimensionless'
515
+ @physical_quantity = 'dimensionless'
518
516
  base_quantities.each { |var| remove_instance_variable(var) }
519
517
  end
520
518
 
@@ -4,7 +4,38 @@ module Quantify
4
4
  self.module_eval &block if block
5
5
  end
6
6
 
7
+ # Check whether superscript characters are turned on.
8
+ def self.use_superscript_characters?
9
+ @use_superscript_characters.nil? ? true : @use_superscript_characters
10
+ end
11
+
12
+ # Shorthand method for Quantify.use_superscript_characters=true
13
+ def self.use_superscript_characters!
14
+ self.use_superscript_characters=true
15
+ end
7
16
 
17
+ # Declare whether superscript characters should be used for unit names, symbols
18
+ # and labels - i.e. "²" and "³" rather than "^2" and "^3". Set to either true or
19
+ # false. If not set, superscript characters are used by default.
20
+ #
21
+ def self.use_superscript_characters=(true_or_false)
22
+ raise Exceptions::InvalidArgumentError,
23
+ "Argument must be true or false" unless true_or_false == true || true_or_false == false
24
+ @use_superscript_characters = true_or_false
25
+ refresh_all_unit_identifiers!
26
+ end
27
+
28
+ # Switch all unit identifiers (name, symbol, label) to use the currently
29
+ # configured system for superscripts.
30
+ #
31
+ def refresh_all_unit_identifiers!
32
+ Unit.units.replace(
33
+ Unit.units.map do |unit|
34
+ unit.refresh_identifiers!
35
+ unit
36
+ end
37
+ )
38
+ end
8
39
 
9
40
  module ExtendedMethods
10
41
 
@@ -17,7 +48,7 @@ module Quantify
17
48
  #
18
49
  def method_missing(method, *args, &block)
19
50
  if method.to_s =~ /((si|non_si|compound)_)?(non_(prefixed)_)?((base|derived|benchmark)_)?units(_by_(name|symbol|label))?/
20
- if $2 or $4 or $6
51
+ if $2 || $4 || $6
21
52
  conditions = []
22
53
  conditions << "unit.is_#{$2}_unit?" if $2
23
54
  conditions << "!unit.is_prefixed_unit?" if $4
@@ -81,19 +81,19 @@ module Quantify
81
81
  # Quantity.new(123.456, :degree_celsius).represents
82
82
  # #=> :temperature
83
83
  def represents
84
- self.unit.measures
84
+ @unit.measures
85
85
  end
86
86
 
87
87
  # Returns a string representation of the quantity, using the unit symbol
88
88
  def to_s format=:symbol
89
89
  if format == :name
90
- if self.value == 1 or self.value == -1
91
- "#{self.value} #{self.unit.name}"
90
+ if @value == 1 || @value == -1
91
+ "#{@value} #{@unit.name}"
92
92
  else
93
- "#{self.value} #{self.unit.pluralized_name}"
93
+ "#{@value} #{@unit.pluralized_name}"
94
94
  end
95
95
  else
96
- "#{self.value} #{self.unit.send format}"
96
+ "#{@value} #{@unit.send format}"
97
97
  end
98
98
  end
99
99
 
@@ -116,20 +116,20 @@ module Quantify
116
116
  def to(new_unit)
117
117
  new_unit = Unit.for new_unit
118
118
  if is_basic_conversion_with_scalings? new_unit
119
- Quantity.new(value,unit).conversion_with_scalings! new_unit
119
+ Quantity.new(@value,@unit).conversion_with_scalings! new_unit
120
120
  elsif self.unit.is_alternative_for? new_unit
121
- Quantity.new(value,unit).convert_to_equivalent_unit! new_unit
121
+ Quantity.new(@value,@unit).convert_to_equivalent_unit! new_unit
122
122
  elsif self.unit.is_compound_unit?
123
- Quantity.new(value,unit).convert_compound_unit_to_non_equivalent_unit! new_unit
123
+ Quantity.new(@value,@unit).convert_compound_unit_to_non_equivalent_unit! new_unit
124
124
  else
125
125
  nil # raise? or ...
126
126
  end
127
127
  end
128
128
 
129
129
  def is_basic_conversion_with_scalings?(new_unit)
130
- return true if (self.unit.has_scaling? or new_unit.has_scaling?) and
131
- not self.unit.is_compound_unit? and
132
- not new_unit.is_compound_unit?
130
+ return true if (@unit.has_scaling? || new_unit.has_scaling?) &&
131
+ !@unit.is_compound_unit? &&
132
+ !new_unit.is_compound_unit?
133
133
  return false
134
134
  end
135
135
 
@@ -139,14 +139,14 @@ module Quantify
139
139
  # base units
140
140
  #
141
141
  def convert_to_equivalent_unit!(new_unit)
142
- old_unit = unit
142
+ old_unit = @unit
143
143
  self.multiply!(Unit.ratio new_unit, old_unit)
144
144
  old_base_units = old_unit.base_units.map { |base| base.unit } if old_unit.is_compound_unit?
145
145
  self.cancel_base_units!(*old_base_units || old_unit)
146
146
  end
147
147
 
148
148
  def conversion_with_scalings!(new_unit)
149
- @value = (((self.value + self.unit.scaling) * self.unit.factor) / new_unit.factor) - new_unit.scaling
149
+ @value = (((@value + @unit.scaling) * @unit.factor) / new_unit.factor) - new_unit.scaling
150
150
  @unit = new_unit
151
151
  return self
152
152
  end
@@ -158,7 +158,7 @@ module Quantify
158
158
  # Unit.kilowatt_hour.to :second #=> 'kilowatt second'
159
159
  #
160
160
  def convert_compound_unit_to_non_equivalent_unit!(new_unit)
161
- self.unit.base_units.select do |base|
161
+ @unit.base_units.select do |base|
162
162
  base.unit.is_alternative_for? new_unit
163
163
  end.inject(self) do |quantity,base|
164
164
  factor = Unit.ratio(new_unit**base.index, base.unit**base.index)
@@ -168,16 +168,16 @@ module Quantify
168
168
 
169
169
  # Converts a quantity to the equivalent quantity using only SI units
170
170
  def to_si
171
- if self.unit.is_compound_unit?
172
- Quantity.new(value,unit).convert_compound_unit_to_si!
171
+ if @unit.is_compound_unit?
172
+ Quantity.new(@value,@unit).convert_compound_unit_to_si!
173
173
  else
174
- self.to(unit.si_unit)
174
+ self.to(@unit.si_unit)
175
175
  end
176
176
  end
177
177
 
178
178
  def convert_compound_unit_to_si!
179
- until self.unit.is_base_quantity_si_unit? do
180
- unit = self.unit.base_units.find do |base|
179
+ until @unit.is_base_quantity_si_unit? do
180
+ unit = @unit.base_units.find do |base|
181
181
  !base.is_base_quantity_si_unit?
182
182
  end.unit
183
183
  self.convert_compound_unit_to_non_equivalent_unit!(unit.si_unit)
@@ -192,9 +192,9 @@ module Quantify
192
192
  #
193
193
  def add_or_subtract!(operator,other)
194
194
  if other.is_a? Quantity
195
- other = other.to(unit) if other.unit.is_alternative_for?(unit)
196
- if self.unit == other.unit
197
- @value = value.send operator, other.value
195
+ other = other.to(@unit) if other.unit.is_alternative_for?(@unit)
196
+ if @unit.is_equivalent_to? other.unit
197
+ @value = @value.send operator, other.value
198
198
  return self
199
199
  else
200
200
  raise Quantify::Exceptions::InvalidObjectError "Cannot add or subtract Quantities with different dimensions"
@@ -206,11 +206,11 @@ module Quantify
206
206
 
207
207
  def multiply_or_divide!(operator,other)
208
208
  if other.kind_of? Numeric
209
- @value = value.send(operator,other)
209
+ @value = @value.send(operator,other)
210
210
  return self
211
211
  elsif other.kind_of? Quantity
212
- @unit = unit.send(operator,other.unit).or_equivalent
213
- @value = value.send(operator,other.value)
212
+ @unit = @unit.send(operator,other.unit).or_equivalent
213
+ @value = @value.send(operator,other.value)
214
214
  return self
215
215
  else
216
216
  raise Quantify::Exceptions::InvalidArgumentError "Cannot multiply or divide a Quantity by a non-Quantity or non-Numeric object"
@@ -219,8 +219,8 @@ module Quantify
219
219
 
220
220
  def pow!(power)
221
221
  raise Exceptions::InvalidArgumentError, "Argument must be an integer" unless power.is_a? Integer
222
- @value = value ** power
223
- @unit = unit ** power
222
+ @value = @value ** power
223
+ @unit = @unit ** power
224
224
  return self
225
225
  end
226
226
 
@@ -241,34 +241,34 @@ module Quantify
241
241
  end
242
242
 
243
243
  def add(other)
244
- Quantity.new(value,unit).add!(other)
244
+ Quantity.new(@value,@unit).add!(other)
245
245
  end
246
246
  alias :+ :add
247
247
 
248
248
  def subtract(other)
249
- Quantity.new(value,unit).subtract!(other)
249
+ Quantity.new(@value,@unit).subtract!(other)
250
250
  end
251
251
  alias :- :subtract
252
252
 
253
253
  def multiply(other)
254
- Quantity.new(value,unit).multiply!(other)
254
+ Quantity.new(@value,@unit).multiply!(other)
255
255
  end
256
256
  alias :times :multiply
257
257
  alias :* :multiply
258
258
 
259
259
  def divide(other)
260
- Quantity.new(value,unit).divide!(other)
260
+ Quantity.new(@value,@unit).divide!(other)
261
261
  end
262
262
  alias :/ :divide
263
263
 
264
264
  def pow(power)
265
- Quantity.new(value,unit).pow!(power)
265
+ Quantity.new(@value,@unit).pow!(power)
266
266
  end
267
267
  alias :** :pow
268
268
 
269
269
  def rationalize_units
270
- return self unless unit.is_a? Unit::Compound
271
- self.to unit.clone.rationalize_base_units!
270
+ return self unless @unit.is_a? Unit::Compound
271
+ self.to @unit.clone.rationalize_base_units!
272
272
  end
273
273
 
274
274
  def rationalize_units!
@@ -279,7 +279,7 @@ module Quantify
279
279
  end
280
280
 
281
281
  def cancel_base_units!(*units)
282
- @unit = unit.cancel_base_units!(*units) if unit.is_compound_unit?
282
+ @unit = @unit.cancel_base_units!(*units) if @unit.is_compound_unit?
283
283
  return self
284
284
  end
285
285
 
@@ -304,8 +304,8 @@ module Quantify
304
304
  def <=>(other)
305
305
  raise Exceptions::InvalidArgumentError unless other.is_a? Quantity
306
306
  raise Exceptions::InvalidArgumentError unless other.unit.is_alternative_for?(unit)
307
- other = other.to unit
308
- value.to_f <=> other.value.to_f
307
+ other = other.to @unit
308
+ @value.to_f <=> other.value.to_f
309
309
  end
310
310
 
311
311
  def ===(range)
@@ -45,7 +45,7 @@ module Quantify
45
45
  #
46
46
  def self.construct(unit,&block)
47
47
  new_unit = self.new unit.to_hash
48
- yield new_unit if block_given?
48
+ block.call(new_unit) if block_given?
49
49
  return new_unit
50
50
  end
51
51
 
@@ -64,8 +64,7 @@ module Quantify
64
64
  class_eval &block if block
65
65
  end
66
66
 
67
- attr_accessor :name, :symbol, :label, :factor
68
- attr_reader :dimensions
67
+ attr_reader :name, :symbol, :label, :factor, :dimensions
69
68
  attr_reader :acts_as_alternative_unit, :acts_as_equivalent_unit
70
69
 
71
70
  # Create a new Unit::Base instance.
@@ -100,34 +99,88 @@ module Quantify
100
99
  # representation in the Dimensions class. This dimensions attribute is to
101
100
  # provide much of the unit functionality
102
101
  #
103
- def initialize(options=nil)
102
+ def initialize(options=nil,&block)
104
103
  @acts_as_alternative_unit = true
105
104
  @acts_as_equivalent_unit = false
106
- @factor = 1.0
107
- @symbol = nil
108
- @label = nil
105
+ self.factor = 1.0
106
+ self.symbol = nil
107
+ self.label = nil
109
108
  if options.is_a? Hash
110
109
  self.dimensions = options[:dimensions] || options[:physical_quantity]
111
- @name = options[:name].standardize.singularize.downcase
112
- @factor = options[:factor].to_f if options[:factor]
113
- @symbol = options[:symbol].standardize if options[:symbol]
114
- @label = options[:label].to_s if options[:label]
110
+ self.name = options[:name]
111
+ self.factor = options[:factor] if options[:factor]
112
+ self.symbol = options[:symbol] if options[:symbol]
113
+ self.label = options[:label] if options[:label]
115
114
  end
116
- yield self if block_given?
115
+ block.call(self) if block_given?
117
116
  valid?
118
117
  end
119
118
 
119
+ # Set the dimensions attribute of self. Valid arguments passed in are (1)
120
+ # instances of the Dimensions class; or (2) string or symbol matching
121
+ # the physical quantity attribute of a known Dimensions object.
122
+ #
120
123
  def dimensions=(dimensions)
121
124
  if dimensions.is_a? Dimensions
122
125
  @dimensions = dimensions
123
- elsif dimensions.is_a? String or dimensions.is_a? Symbol
124
- @dimensions = Dimensions.for dimensions
126
+ elsif dimensions.is_a?(String) || dimensions.is_a?(Symbol)
127
+ @dimensions = Dimensions.for(dimensions)
125
128
  else
126
129
  raise Exceptions::InvalidArgumentError, "Unknown physical_quantity specified"
127
130
  end
128
131
  end
129
132
  alias :physical_quantity= :dimensions=
130
133
 
134
+ # Set the name attribute of self. Names are stringified, singlularized and
135
+ # stripped of underscores. Superscripts are formatted according to the
136
+ # configuration found in Quantify.use_superscript_characters? Names are NOT
137
+ # case sensitive (retrieving units by name can use any or mixed cases).
138
+ #
139
+ def name=(name)
140
+ name = name.to_s.remove_underscores.singularize
141
+ @name = Quantify.use_superscript_characters? ? name.with_superscript_characters : name.without_superscript_characters
142
+ end
143
+
144
+ # Set the symbol attribute of self. Symbols are stringified and stripped of
145
+ # any underscores. Superscripts are formatted according to the configuration
146
+ # found in Quantify.use_superscript_characters?
147
+ #
148
+ # Conventional symbols for units and unit prefixes prescribe case clearly
149
+ # (e.g. 'm' => metre, 'M' => mega-; 'g' => gram, 'G' => giga-) and
150
+ # therefore symbols ARE case senstive.
151
+ #
152
+ def symbol=(symbol)
153
+ symbol = symbol.to_s.remove_underscores
154
+ @symbol = Quantify.use_superscript_characters? ? symbol.with_superscript_characters : symbol.without_superscript_characters
155
+ end
156
+
157
+ # Set the label attribute of self. This represents the unique identifier for
158
+ # the unit, and follows JScience for many standard units and general
159
+ # formatting (e.g. underscores, forward slashes, middots).
160
+ #
161
+ # Labels are stringified and superscripts are formatted according to the
162
+ # configuration found in Quantify.use_superscript_characters?
163
+ #
164
+ # Labels are a unique consistent reference and are therefore case senstive.
165
+ #
166
+ def label=(label)
167
+ label = label.to_s.gsub(" ","_")
168
+ @label = Quantify.use_superscript_characters? ? label.with_superscript_characters : label.without_superscript_characters
169
+ end
170
+
171
+ # Refresh the name, symbol and label attributes of self with respect to the
172
+ # configuration found in Quantify.use_superscript_characters?
173
+ #
174
+ def refresh_identifiers!
175
+ self.name = name
176
+ self.symbol = symbol
177
+ self.label = label
178
+ end
179
+
180
+ def factor=(factor)
181
+ @factor = factor.to_f
182
+ end
183
+
131
184
  # Permits a block to be used, operating on self. This is useful for modifying
132
185
  # the attributes of an already instantiated unit, especially when defining
133
186
  # units on the basis of operation on existing units for adding specific
@@ -139,17 +192,17 @@ module Quantify
139
192
  # unit.name = 'pound per square inch'
140
193
  # end
141
194
  #
142
- def configure
143
- yield self if block_given?
195
+ def configure(&block)
196
+ block.call(self) if block_given?
144
197
  return self if valid?
145
198
  end
146
199
 
147
200
  # Similar to #configure but makes the new unit configuration the canonical
148
201
  # unit for self.label
149
202
  #
150
- def configure_as_canonical &block
203
+ def configure_as_canonical(&block)
151
204
  unload if loaded?
152
- configure &block if block_given?
205
+ configure(&block) if block_given?
153
206
  make_canonical
154
207
  end
155
208
 
@@ -158,8 +211,8 @@ module Quantify
158
211
  # If a block is given, the unit can be configured prior to loading, in a
159
212
  # similar to way to the #configure method.
160
213
  #
161
- def load
162
- yield self if block_given?
214
+ def load(&block)
215
+ block.call(self) if block_given?
163
216
  raise Exceptions::InvalidArgumentError, "A unit with the same label: #{self.name}) already exists" if loaded?
164
217
  Quantify::Unit.units << self if valid?
165
218
  return self
@@ -224,14 +277,14 @@ module Quantify
224
277
  end
225
278
 
226
279
  def pluralized_name
227
- self.name.pluralize
280
+ @name.pluralize
228
281
  end
229
282
 
230
283
  # Determine if the unit represents one of the base quantities, length,
231
284
  # mass, time, temperature, etc.
232
285
  #
233
286
  def is_base_unit?
234
- Dimensions::BASE_QUANTITIES.map(&:standardize).include? self.measures
287
+ Dimensions::BASE_QUANTITIES.map {|base| base.remove_underscores }.include? self.measures
235
288
  end
236
289
 
237
290
  # Determine if the unit is THE canonical SI unit for a base quantity (length,
@@ -239,20 +292,20 @@ module Quantify
239
292
  # returning true only for metre, kilogram, second, Kelvin, etc.
240
293
  #
241
294
  def is_base_quantity_si_unit?
242
- is_si_unit? and is_base_unit? and is_benchmark_unit?
295
+ is_si_unit? && is_base_unit? && is_benchmark_unit?
243
296
  end
244
297
 
245
298
  # Determine is the unit is a derived unit - that is, a unit made up of more
246
299
  # than one of the base quantities
247
300
  #
248
301
  def is_derived_unit?
249
- not is_base_unit?
302
+ !is_base_unit?
250
303
  end
251
304
 
252
305
  # Determine if the unit is a prefixed unit
253
306
  def is_prefixed_unit?
254
- return true if valid_prefixes.size > 0 and
255
- self.name =~ /\A(#{valid_prefixes.map(&:name).join("|")})/
307
+ return true if valid_prefixes.size > 0 &&
308
+ self.name =~ /\A(#{valid_prefixes.map {|p| p.name}.join("|")})/
256
309
  return false
257
310
  end
258
311
 
@@ -263,7 +316,7 @@ module Quantify
263
316
  # containing a prefix. This oddity makes this method useful/necessary.
264
317
  #
265
318
  def is_benchmark_unit?
266
- self.factor == 1.0
319
+ @factor == 1.0
267
320
  end
268
321
 
269
322
  # Determine is a unit object represents an SI named unit
@@ -283,18 +336,18 @@ module Quantify
283
336
  end
284
337
 
285
338
  def is_dimensionless?
286
- self.dimensions.is_dimensionless?
339
+ @dimensions.is_dimensionless?
287
340
  end
288
341
 
289
- # Determine if self is the same unit as another. Similarity is based on
342
+ # Determine if self is equivalent to another. Equivalency is based on
290
343
  # representing the same physical quantity (i.e. dimensions) and the same
291
344
  # factor and scaling values.
292
345
  #
293
- # Unit.metre.is_same_as? Unit.foot #=> false
346
+ # Unit.metre.is_equivalent_to? Unit.foot #=> false
294
347
  #
295
- # Unit.metre.is_same_as? Unit.gram #=> false
348
+ # Unit.metre.is_equivalent_to? Unit.gram #=> false
296
349
  #
297
- # Unit.metre.is_same_as? Unit.metre #=> true
350
+ # Unit.metre.is_equivalent_to? Unit.metre #=> true
298
351
  #
299
352
  # The base_units attr of Compound units are not compared. Neither are the
300
353
  # names or symbols. This is because we want to recognise cases where units
@@ -303,25 +356,24 @@ module Quantify
303
356
  # example, if we build a unit for energy using only SI units, we want to
304
357
  # recognise this as a joule, rather than a kg m^2 s^-2, e.g.
305
358
  #
306
- # (Unit.kg*Unit.m*Unit.m/Unit.s/Unit.s).is_same_as? Unit.joule
359
+ # (Unit.kg*Unit.m*Unit.m/Unit.s/Unit.s).is_equivalent_to? Unit.joule
307
360
  #
308
361
  # #=> true
309
362
  #
310
- def is_same_as?(other)
363
+ def is_equivalent_to?(other)
311
364
  [:dimensions,:factor,:scaling].all? do |attr|
312
365
  self.send(attr) == other.send(attr)
313
366
  end
314
367
  end
315
-
316
- alias :== :is_same_as?
317
368
 
318
369
  # Check if unit has the identity as another, i.e. the same label. This is
319
370
  # used to determine if a unit with the same accessors already exists in
320
371
  # the module variable @@units
321
372
  #
322
373
  def has_same_identity_as?(other)
323
- self.label == other.label and not self.label.nil?
374
+ @label == other.label && !@label.nil?
324
375
  end
376
+ alias :== :has_same_identity_as?
325
377
 
326
378
  # Determine if another unit is an alternative unit for self, i.e. do the two
327
379
  # units represent the same physical quantity. This is established by compraing
@@ -334,7 +386,7 @@ module Quantify
334
386
  # Unit.metre.is_alternative_for? Unit.metre #=> true
335
387
  #
336
388
  def is_alternative_for?(other)
337
- other.dimensions == self.dimensions
389
+ other.dimensions == @dimensions
338
390
  end
339
391
 
340
392
  # List the alternative units for self, i.e. the other units which share
@@ -348,8 +400,8 @@ module Quantify
348
400
  # are returned within the array
349
401
  #
350
402
  def alternatives(by=nil)
351
- self.dimensions.units(nil).reject do |unit|
352
- unit.is_same_as? self or not unit.acts_as_alternative_unit
403
+ @dimensions.units(nil).reject do |unit|
404
+ unit.is_equivalent_to?(self) || !unit.acts_as_alternative_unit
353
405
  end.map(&by)
354
406
  end
355
407
 
@@ -357,18 +409,18 @@ module Quantify
357
409
  # by self, e.g.
358
410
  #
359
411
  def si_unit
360
- self.dimensions.si_unit
412
+ @dimensions.si_unit
361
413
  end
362
414
 
363
415
  def valid?
364
- return true if valid_descriptors? and valid_dimensions?
416
+ return true if valid_descriptors? && valid_dimensions?
365
417
  raise Exceptions::InvalidArgumentError, "Unit definition must include a name, a symbol, a label and physical quantity"
366
418
  end
367
419
 
368
420
  def valid_descriptors?
369
421
  [:name, :symbol, :label].all? do |attr|
370
422
  attribute = send(attr)
371
- attribute.is_a? String and not attribute.empty?
423
+ attribute.is_a?(String) && !attribute.empty?
372
424
  end
373
425
  end
374
426
 
@@ -396,7 +448,7 @@ module Quantify
396
448
  # "T", "P" ... ]
397
449
  #
398
450
  def valid_prefixes(by=nil)
399
- return empty_array = [] if self.is_compound_unit?
451
+ return [] if self.is_compound_unit?
400
452
  return Unit::Prefix.si_prefixes.map(&by) if is_si_unit?
401
453
  return Unit::Prefix.non_si_prefixes.map(&by) if is_non_si_unit?
402
454
  end
@@ -406,7 +458,7 @@ module Quantify
406
458
  #
407
459
  def multiply(other)
408
460
  options = []
409
- self.instance_of?(Unit::Compound) ? options += self.base_units : options << self
461
+ self.instance_of?(Unit::Compound) ? options += @base_units : options << self
410
462
  other.instance_of?(Unit::Compound) ? options += other.base_units : options << other
411
463
  Unit::Compound.new(*options)
412
464
  end
@@ -421,7 +473,7 @@ module Quantify
421
473
  #
422
474
  def divide(other)
423
475
  options = []
424
- self.instance_of?(Unit::Compound) ? options += self.base_units : options << self
476
+ self.instance_of?(Unit::Compound) ? options += @base_units : options << self
425
477
 
426
478
  if other.instance_of? Unit::Compound
427
479
  options += other.base_units.map { |base| base.index *= -1; base }
@@ -461,7 +513,7 @@ module Quantify
461
513
  # of self, complete with modified name, symbol, factor, etc..
462
514
  #
463
515
  def with_prefix(name_or_symbol)
464
- if self.name =~ /\A(#{valid_prefixes(:name).join("|")})/
516
+ if @name =~ /\A(#{valid_prefixes(:name).join("|")})/
465
517
  raise Exceptions::InvalidArgumentError, "Cannot add prefix where one already exists: #{self.name}"
466
518
  end
467
519
 
@@ -469,11 +521,11 @@ module Quantify
469
521
 
470
522
  unless prefix.nil?
471
523
  new_unit_options = {}
472
- new_unit_options[:name] = "#{prefix.name}#{self.name}"
473
- new_unit_options[:symbol] = "#{prefix.symbol}#{self.symbol}"
474
- new_unit_options[:label] = "#{prefix.symbol}#{self.label}"
475
- new_unit_options[:factor] = prefix.factor * self.factor
476
- new_unit_options[:physical_quantity] = self.dimensions
524
+ new_unit_options[:name] = "#{prefix.name}#{@name}"
525
+ new_unit_options[:symbol] = "#{prefix.symbol}#{@symbol}"
526
+ new_unit_options[:label] = "#{prefix.symbol}#{@label}"
527
+ new_unit_options[:factor] = prefix.factor * @factor
528
+ new_unit_options[:physical_quantity] = @dimensions
477
529
  self.class.new(new_unit_options)
478
530
  else
479
531
  raise Exceptions::InvalidArgumentError, "Prefix unit is not known: #{prefix}"
@@ -503,7 +555,7 @@ module Quantify
503
555
  # (1/unit).symbol #=> "m^-1"
504
556
  #
505
557
  def coerce(object)
506
- if object.kind_of? Numeric and object == 1
558
+ if object.kind_of?(Numeric) && object == 1
507
559
  return Unit.unity, self
508
560
  else
509
561
  raise Exceptions::InvalidArgumentError, "Cannot coerce #{self.class} into #{object.class}"
@@ -520,9 +572,9 @@ module Quantify
520
572
  #
521
573
  def initialize_copy(source)
522
574
  super
523
- instance_variable_set("@dimensions", dimensions.clone)
575
+ instance_variable_set("@dimensions", @dimensions.clone)
524
576
  if self.is_compound_unit?
525
- instance_variable_set("@base_units", base_units.map {|base| base.clone })
577
+ instance_variable_set("@base_units", @base_units.map {|base| base.clone })
526
578
  end
527
579
  end
528
580
 
@@ -537,12 +589,12 @@ module Quantify
537
589
  # is equaivalent to Unit.m.alternatives :name
538
590
  #
539
591
  def method_missing(method, *args, &block)
540
- if method.to_s =~ /(to_)(.*)/ and prefix = Prefix.for($2.to_sym)
541
- return self.with_prefix prefix
542
- elsif method.to_s =~ /(alternatives_by_)(.*)/ and self.respond_to? $2.to_sym
543
- return self.alternatives $2.to_sym
544
- elsif method.to_s =~ /(valid_prefixes_by_)(.*)/ and Prefix::Base.instance_methods.include? $2.to_s
545
- return self.valid_prefixes $2.to_sym
592
+ if method.to_s =~ /(to_)(.*)/ && prefix = Prefix.for($2.to_sym)
593
+ return self.with_prefix(prefix)
594
+ elsif method.to_s =~ /(alternatives_by_)(.*)/ && self.respond_to?($2.to_sym)
595
+ return self.alternatives($2.to_sym)
596
+ elsif method.to_s =~ /(valid_prefixes_by_)(.*)/ && Prefix::Base.instance_methods.include?($2.to_s)
597
+ return self.valid_prefixes($2.to_sym)
546
598
  end
547
599
  super
548
600
  end