Module: Quantify::Unit

Extended by:
ExtendedMethods
Defined in:
lib/quantify/unit/unit.rb,
lib/quantify/unit/si_unit.rb,
lib/quantify/unit/base_unit.rb,
lib/quantify/unit/non_si_unit.rb,
lib/quantify/unit/compound_unit.rb,
lib/quantify/unit/prefix/prefix.rb,
lib/quantify/unit/prefix/si_prefix.rb,
lib/quantify/unit/compound_base_unit.rb,
lib/quantify/unit/prefix/base_prefix.rb,
lib/quantify/unit/prefix/non_si_prefix.rb,
lib/quantify/unit/compound_base_unit_list.rb

Defined Under Namespace

Modules: Prefix Classes: Base, Compound, CompoundBaseUnit, CompoundBaseUnitList, NonSI, SI

Constant Summary collapse

NUMBER_REGEX =

The Unit module contains functionality for defining and handling representations of physical units.

All units are defined using the Unit::SI and Unit::NonSI classes, both of which inherit from Unit::Base.

New units can be defined to represent whatever is required. However a system of known units is stored in the Unit module instance variable @units, accessible using Unit.units. These known units can be configured to represent which ever units are required. The Unit module will handle any combinations of units and prefixes according to the known units and prefixes specified in config.rb. New units can be defined (with or without prefixes) at any time and either used in place or loaded into the known system.

/([\d\s.,]+)/i
UNIT_DENOMINATOR_REGEX =
/(\/|per)/i
ORDINAL_SUFFIXES_REGEX =
/(st|nd|rd|th)\b/i
UNIT_PREFIX_TERMS_REGEX =
/\A(square|cubic)\b/i
INDEX_REGEX =
/\^?([\d\.-]*)/
WORD_WITH_INDEX_REGEX =
/([^\d\s.,\^]+)#{INDEX_REGEX}?/i
UNIT_SUFFIX_TERMS_REGEX =
/\A(squared|cubed|to the \d+(#{ORDINAL_SUFFIXES_REGEX}) power)\b/i
QUANTITY_REGEX =
/#{Unit::NUMBER_REGEX}(#{Quantify::Unit::WORD_WITH_INDEX_REGEX})/i

Class Attribute Summary collapse

Class Method Summary collapse

Methods included from ExtendedMethods

method_missing

Class Attribute Details

.unitsObject (readonly)

Returns the value of attribute units.



41
42
43
# File 'lib/quantify/unit/unit.rb', line 41

def units
  @units
end

Class Method Details

.base_quantity_si_unitsObject

This returns the suite of units which represents THE SI units for each of the base dimensions, i.e. metre, kilogram, second, etc. but not prefixed versions of the same unit



272
273
274
# File 'lib/quantify/unit/unit.rb', line 272

def self.base_quantity_si_units
  @units.select {|unit| unit.is_base_quantity_si_unit? }
end

.configure(&block) ⇒ Object



47
48
49
# File 'lib/quantify/unit/unit.rb', line 47

def self.configure(&block)
  self.class_eval(&block) if block
end

.dimensionlessObject



193
194
195
# File 'lib/quantify/unit/unit.rb', line 193

def self.dimensionless
  Unit::Base.new(:dimensions => 'dimensionless')
end

.for(name_symbol_label_or_object) ⇒ Object

Retrieve an object representing the specified unit.

Argument can be the unit name, symbol or JScience label and provided as a string or a symbol, e.g.

Unit.for :metre

Unit.for 'kilogram'

This can be shortened to, for example, Unit.metre by virtue of the #method_missing method (see below)

This method will recognise valid combinations of known units and prefixes, irrespective of whether the prefixed unit has been initialized into the system of known units in it’s own right. For example,

Unit.centimetre ... or, alternatively ... Unit.cm

will return a Unit::SI object with attributes representing a centimetre based on the initialized Unit for :metre and Prefix :centi.



218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
# File 'lib/quantify/unit/unit.rb', line 218

def self.for(name_symbol_label_or_object)
  return name_symbol_label_or_object.clone if name_symbol_label_or_object.is_a? Unit::Base
  return nil if name_symbol_label_or_object.nil? ||
    ( name_symbol_label_or_object.is_a?(String) && name_symbol_label_or_object.empty? )
  name_symbol_or_label = name_symbol_label_or_object
  unless name_symbol_or_label.is_a?(String) || name_symbol_or_label.is_a?(Symbol)
    raise Exceptions::InvalidArgumentError, "Argument must be a Symbol or String"
  end
  if unit = Unit.match(name_symbol_or_label)
    return unit
  elsif unit = Unit.parse(name_symbol_or_label)
    return unit
  elsif unit = Unit.parse(name_symbol_or_label, :iterative => true)
    return unit
  else
    return nil
  end
rescue Exceptions::InvalidUnitError
  return nil
end

.load(unit) ⇒ Object

Load a new unit into they system of known units



160
161
162
# File 'lib/quantify/unit/unit.rb', line 160

def self.load(unit)
  @units << unit if unit.is_a? Unit::Base
end

.match(name_symbol_or_label) ⇒ Object



239
240
241
242
243
244
# File 'lib/quantify/unit/unit.rb', line 239

def self.match(name_symbol_or_label)
  return name_symbol_or_label.clone if name_symbol_or_label.is_a? Unit::Base
  Unit.match_known_unit_or_prefixed_variant(:label, name_symbol_or_label) or
  Unit.match_known_unit_or_prefixed_variant(:name, name_symbol_or_label) or
  Unit.match_known_unit_or_prefixed_variant(:symbol, name_symbol_or_label)
end

.non_prefixed_unitsObject

This can be replicated by method missing approach, but explicit method provided given importance in #match (and #for) methods regexen



279
280
281
# File 'lib/quantify/unit/unit.rb', line 279

def self.non_prefixed_units
  @units.select {|unit| !unit.is_prefixed_unit? }
end

.non_si_non_prefixed_unitsObject

This can be replicated by method missing approach, but explicit method provided given importance in #match (and #for) methods regexen



293
294
295
# File 'lib/quantify/unit/unit.rb', line 293

def self.non_si_non_prefixed_units
  @units.select {|unit| unit.is_non_si_unit? && !unit.is_prefixed_unit? }
end

.parse(string, options = {}) ⇒ Object

Parse complex strings into unit.



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/quantify/unit/unit.rb', line 248

def self.parse(string, options={})
  string = string.remove_underscores.without_superscript_characters
  if options[:iterative] == true
    units = Unit.iterative_parse(string, options) 
    units, remainder = units if options[:remainder] == true
  else
    units = Unit.simple_parse(string)
  end

  if units.empty?
    units = nil 
  elsif units.size == 1 && units.first.index == 1
    units = units.first.unit
  else
    units = Unit::Compound.new(*units)
  end

  options[:iterative] == true && options[:iterative] == true ? [units, remainder] : units
end

.ratio(unit, other_unit) ⇒ Object

Returns an instance of the class Quantity which represents the ratio of two units. For example, the ratio of miles to kilometers is 1.609355, or there are 1.609355 km in 1 mile.

ratio = Unit.ratio :km, :mi         #=> <Quantify::Quantity:0xj9ab878a7>

ratio.to_s :name                    #=> "1.609344 kilometres per mile"

In other words the quantity represents the definition of one unit in terms of the other.



182
183
184
185
186
187
188
189
190
191
# File 'lib/quantify/unit/unit.rb', line 182

def self.ratio(unit,other_unit)
  unit = Unit.for unit
  other_unit = Unit.for other_unit
  unless unit.is_alternative_for? other_unit
    raise Exceptions::InvalidUnitError, "Units do not represent the same physical quantity"
  end
  new_unit = (unit / other_unit)
  value = 1/new_unit.factor
  Quantity.new(value, new_unit)
end

.refresh_all_unit_attributes!Object

Switch all unit identifiers (name, symbol, label) to use the currently configured system for superscripts.



153
154
155
156
157
# File 'lib/quantify/unit/unit.rb', line 153

def self.refresh_all_unit_attributes!
  Unit.units.replace(
    Unit.units.map { |unit| unit.refresh_attributes; unit }
  )
end

.si_non_prefixed_unitsObject

This can be replicated by method missing approach, but explicit method provided given importance in #match (and #for) methods regexen



286
287
288
# File 'lib/quantify/unit/unit.rb', line 286

def self.si_non_prefixed_units
  @units.select {|unit| unit.is_si_unit? && !unit.is_prefixed_unit? }
end

.symbol_denominator_delimiterObject



59
60
61
# File 'lib/quantify/unit/unit.rb', line 59

def self.symbol_denominator_delimiter
  @symbol_denominator_delimiter ||= "/"
end

.symbol_denominator_delimiter=(string) ⇒ Object

Set the default string which is used to delimit numerator and denominator strings in compound unit symbol representations. Defaults to “/”.



54
55
56
57
# File 'lib/quantify/unit/unit.rb', line 54

def self.symbol_denominator_delimiter=(string)
  @symbol_denominator_delimiter = string
  refresh_all_unit_attributes!
end

.symbol_unit_delimiterObject



71
72
73
# File 'lib/quantify/unit/unit.rb', line 71

def self.symbol_unit_delimiter
  @symbol_unit_delimiter ||= " "
end

.symbol_unit_delimiter=(string) ⇒ Object

Set the default string which is used to delimit unit symbol strings in compound unit symbol representations. Defaults to “ ”.



66
67
68
69
# File 'lib/quantify/unit/unit.rb', line 66

def self.symbol_unit_delimiter=(string)
  @symbol_unit_delimiter = string
  refresh_all_unit_attributes!
end

.unload(*unloaded_units) ⇒ Object

Remove a unit from the system of known units



165
166
167
168
169
# File 'lib/quantify/unit/unit.rb', line 165

def self.unload(*unloaded_units)
  [unloaded_units].flatten.each do |unloaded_unit|
    @units.delete(Unit.for(unloaded_unit))
  end
end

.use_superscript_characters!Object

Shorthand method for ::use_superscript_characters=true



135
136
137
# File 'lib/quantify/unit/unit.rb', line 135

def self.use_superscript_characters!
  self.use_superscript_characters = true
end

.use_superscript_characters=(true_or_false) ⇒ Object

Declare whether superscript characters should be used for unit names, symbols and labels - i.e. “²” and “³” rather than “^2” and “^3”. Set to either true or false. If not set, superscript characters are used by default.



143
144
145
146
147
148
# File 'lib/quantify/unit/unit.rb', line 143

def self.use_superscript_characters=(true_or_false)
  raise Exceptions::InvalidArgumentError,
    "Argument must be true or false" unless true_or_false == true || true_or_false == false
  @use_superscript_characters = true_or_false
  refresh_all_unit_attributes!
end

.use_superscript_characters?Boolean

Check whether superscript characters are turned on.

Returns:

  • (Boolean)


130
131
132
# File 'lib/quantify/unit/unit.rb', line 130

def self.use_superscript_characters?
  @use_superscript_characters.nil? ? true : @use_superscript_characters
end

.use_symbol_denominator_syntax!Object

Shorthand bang! method for configuring denominator structures in compound unit symbol representations (e.g. “kg/t km”)



101
102
103
# File 'lib/quantify/unit/unit.rb', line 101

def self.use_symbol_denominator_syntax!
  self.use_symbol_denominator_syntax = true
end

.use_symbol_denominator_syntax=(true_or_false) ⇒ Object

Specify whether denominator structures should be used in compound unit symbol representations. Set either true (e.g. “kg/t km”) or false (e.g. “kg t^-1 km^-1”). Defaults to true



116
117
118
119
# File 'lib/quantify/unit/unit.rb', line 116

def self.use_symbol_denominator_syntax=(true_or_false)
  @use_symbol_denominator_syntax = true_or_false
  refresh_all_unit_attributes!
end

.use_symbol_denominator_syntax?Boolean

Returns true if denominator structures are configured for use within compound unit symbol representations. Otherwise returns false.

Returns:

  • (Boolean)


125
126
127
# File 'lib/quantify/unit/unit.rb', line 125

def self.use_symbol_denominator_syntax?
  @use_symbol_denominator_syntax.nil? ? true : @use_symbol_denominator_syntax
end

.use_symbol_indices_only!Object

Shorthand bang! method for configuring index-only structures in compound unit symbol representations (e.g. “kg t^-1 km^-1”)



108
109
110
# File 'lib/quantify/unit/unit.rb', line 108

def self.use_symbol_indices_only!
  self.use_symbol_denominator_syntax = false
end

.use_symbol_parentheses!Object

Shorthand bang! method for configuring parentheses in compound unit symbol representations



87
88
89
# File 'lib/quantify/unit/unit.rb', line 87

def self.use_symbol_parentheses!
  @use_symbol_parentheses = true
end

.use_symbol_parentheses=(true_or_false) ⇒ Object

Specify whether parentheses should be used to group multiple units in compound unit symbol representations. Set either true (e.g. “kg/(t km)”) or false (e.g. “kg/t km”). Defaults to false



79
80
81
82
# File 'lib/quantify/unit/unit.rb', line 79

def self.use_symbol_parentheses=(true_or_false)
  @use_symbol_parentheses = true_or_false
  refresh_all_unit_attributes!
end

.use_symbol_parentheses?Boolean

Returns true if parentheses are configured for use within compound unit symbol representations. Otherwise returns false.

Returns:

  • (Boolean)


94
95
96
# File 'lib/quantify/unit/unit.rb', line 94

def self.use_symbol_parentheses?
  @use_symbol_parentheses.nil? ? false : @use_symbol_parentheses
end