Class: Quantify::Unit::Compound

Inherits:
Base
  • Object
show all
Defined in:
lib/quantify/unit/compound_unit.rb

Instance Attribute Summary collapse

Attributes inherited from Base

#acts_as_alternative_unit, #base_unit, #dimensions, #factor, #label, #name, #prefix, #symbol

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#alternatives, #canonical_label=, #coerce, #configure, configure, #configure_as_canonical, construct, construct_and_load, #divide, #has_same_identity_as?, #has_scaling?, #is_alternative_for?, #is_base_unit?, #is_benchmark_unit?, #is_compound_unit?, #is_derived_unit?, #is_dimensionless?, #is_equivalent_to?, #is_prefixed_unit?, #load, load, #loaded?, #make_canonical, #measures, #multiply, #pow, prefix_and_load, #reciprocalize, #scaling, #si_unit, #to_hash, #unload, #valid?, #valid_descriptors?, #valid_dimensions?, #with_prefix, #with_prefixes

Methods included from ExtendedMethods

#method_missing

Constructor Details

#initialize(*units, &block) ⇒ Compound

Initialize a compound unit by providing an array containing a represenation of each base unit.

Array may contain elements specified as follows:

1. a instance of CompoundBaseUnit

2. an instance of Unit::Base (in which case its index is assumed as 1

3. a sub-array of size 2 containing an instance of Unit::Base and an
   explicit index


44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/quantify/unit/compound_unit.rb', line 44

def initialize(*units,&block)
  @base_units = CompoundBaseUnitList.new
  units.each do |unit|
    if unit.is_a? CompoundBaseUnit
      @base_units << unit
    elsif unit.is_a? Unit::Base
      @base_units << CompoundBaseUnit.new(unit)
    elsif unit.is_a?(Array) && unit.first.is_a?(Unit::Base) &&
        !unit.first.is_a?(Compound) && unit.size == 2
      @base_units << CompoundBaseUnit.new(unit.first,unit.last)
    else
      raise Exceptions::InvalidArgumentError, "#{unit} does not represent a valid base unit"
    end
  end
  @acts_as_alternative_unit = true
  @acts_as_equivalent_unit = false
  block.call(self) if block_given?
  consolidate_numerator_and_denominator_units!
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Quantify::Unit::Base

Instance Attribute Details

#acts_as_equivalent_unitObject (readonly)

Returns the value of attribute acts_as_equivalent_unit.



30
31
32
# File 'lib/quantify/unit/compound_unit.rb', line 30

def acts_as_equivalent_unit
  @acts_as_equivalent_unit
end

#base_unitsObject (readonly)

Returns the value of attribute base_units.



30
31
32
# File 'lib/quantify/unit/compound_unit.rb', line 30

def base_units
  @base_units
end

Class Method Details

.initialize_prefixed_version(prefix, compound) ⇒ Object

Compound units are units made up of two or more units and powers thereof.

The relationships between these units represent multiplication or division. E.g. a ‘kilowatt hour’ is the unit derived from multiplying a kilowatt and an hour. The ‘kilogram per cubic metre’ similarly represents the kilogram divided by the cubic metre (which itself represents metre x metre x metre).

There are many SI units and NonSI units which are technically compound units - being derived from several base units. For example, the watt represents the joule (itself compound) divided by the second. In this case though, the use of a special name for the unit - the ‘watt’ rather than the ‘kilogram square metre per cubic second’ - allows it to be treated as a standard SI unit.

The Compound class provides support for arbitrarily defined compound units which don’t have well-established names.



23
24
25
26
27
28
# File 'lib/quantify/unit/compound_unit.rb', line 23

def self.initialize_prefixed_version(prefix,compound)
  if compound.has_multiple_base_units? 
    raise Exceptions::InvalidArgumentError, "Cannot apply prefix to compound unit with multiple base units: #{self.name}" 
  end
  super
end

Instance Method Details

#cancel_base_units!(*units) ⇒ Object

Cancel base units across numerator and denominator. If similar units occur in both the numerator and denominator, they can be cancelled, i.e. their powers reduced correspondingly until one is removed.

This method is useful when wanting to remove specific units that can be cancelled from the compound unit configuration while retaining the remaining units in the current format.

If no other potentially cancelable units need to be retained, the method #consolidate_base_units! can be called with the :full argument instead

This method takes an arbitrary number of arguments which represent the units which are required to be cancelled (string, symbol or object)



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

def cancel_base_units!(*units)
  @base_units.cancel!(*units)
  initialize_attributes
end

#consolidate_base_units!Object

Consilidates base quantities by finding multiple instances of the same unit type and reducing them into a single unit representation, by altering the repsective index. It has the effect of raising units to powers and cancelling those which appear in the numerator AND denominator



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

def consolidate_base_units!
  @base_units.consolidate!
  initialize_attributes
end

#consolidate_numerator_and_denominator_units!Object

Similar to #consolidate_base_units! but operates on the numerator and denomiator are separately. This means that two instances of the same unit should not occur in the numerator OR denominator (rather they are combined and the index changed accordingly), but similar units are not cancelled across the numerator and denominators.



164
165
166
167
# File 'lib/quantify/unit/compound_unit.rb', line 164

def consolidate_numerator_and_denominator_units!
  @base_units.consolidate_numerator_and_denominator!
  initialize_attributes
end

#denominator_unitsObject

Returns an array containing only the base units which have negative indices



77
78
79
# File 'lib/quantify/unit/compound_unit.rb', line 77

def denominator_units
  @base_units.denominator_units
end

#equivalent_known_unitObject

Return a known unit which is equivalent to self in terms of its physical quantity (dimensions), factor and scaling attributes (i.e. representing the precise same physical unit but perhaps with different identifiers), e.g.

((Unit.kg*(Unit.m**"))/(Unit.s**2)).equivalent_known_unit.name

                             #=> "joule"


111
112
113
114
115
# File 'lib/quantify/unit/compound_unit.rb', line 111

def equivalent_known_unit
  Unit.units.find do |unit|
    self.is_equivalent_to?(unit) && !unit.is_compound_unit?
  end
end

#has_multiple_base_units?Boolean

Returns:

  • (Boolean)


99
100
101
# File 'lib/quantify/unit/compound_unit.rb', line 99

def has_multiple_base_units?
  @base_units.size > 1
end

#is_base_quantity_si_unit?Boolean

Returns:

  • (Boolean)


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

def is_base_quantity_si_unit?
  @base_units.is_base_quantity_si_unit?
end

#is_non_si_unit?Boolean

Returns:

  • (Boolean)


91
92
93
# File 'lib/quantify/unit/compound_unit.rb', line 91

def is_non_si_unit?
  @base_units.is_non_si_unit?
end

#is_si_unit?Boolean

Determine is a unit object represents an SI named unit.

Returns:

  • (Boolean)


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

def is_si_unit?
  @base_units.is_si_unit?
end

#numerator_unitsObject

Returns an array containing only the base units which have positive indices



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

def numerator_units
  @base_units.numerator_units
end

#or_equivalentObject

Returns an equivalent known unit (via #equivalent_known_unit) if it exists. Otherwise, returns false.



120
121
122
123
124
125
126
127
# File 'lib/quantify/unit/compound_unit.rb', line 120

def or_equivalent
  equivalent_unit = equivalent_known_unit
  if equivalent_unit && equivalent_unit.acts_as_equivalent_unit
    return equivalent_unit
  else
    return self
  end
end

#pluralized_nameObject

Convenient accessor method for pluralized names



82
83
84
# File 'lib/quantify/unit/compound_unit.rb', line 82

def pluralized_name
  @base_units.name(true)
end

#rationalize_base_units!(*units) ⇒ Object

Make compound unit use consistent units for representing each physical quantity. For example, lb/kg => kg/kg.

The units to use for particular physical dimension can be specified. If no unit is specified for a physical quantity which is represented in the self, then the first unit found for that physical quantity is used as the canonical one.



177
178
179
180
# File 'lib/quantify/unit/compound_unit.rb', line 177

def rationalize_base_units!(*units)
  @base_units.rationalize!(*units)
  initialize_attributes
end

#rationalize_numerator_and_denominator_units!(*units) ⇒ Object

Similar to #rationalize_base_units! but operates on the numerator and denomiator are separately. This means that different units representing the same physical quantity may remain across the numerator and denominator units.



187
188
189
190
# File 'lib/quantify/unit/compound_unit.rb', line 187

def rationalize_numerator_and_denominator_units!(*units)
  @base_units.rationalize_numerator_and_denominator!(*units)
  initialize_attributes
end

#refresh_attributesObject

Refresh all unit attributes. Can be used following a change to unit attribute global configurations



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

def refresh_attributes
  initialize_attributes
end