Class: Unitwise::Atom

Inherits:
Base
  • Object
show all
Includes:
Compatible
Defined in:
lib/unitwise/atom.rb

Overview

Atoms are the most basic elements in Unitwise. They are named coded and scaled units without prefixes, multipliers, exponents, etc. Examples are 'meter', 'hour', 'pound force'.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Compatible

#<=>, #compatible_with?, #composition, #composition_string, included, #initialize

Methods inherited from Base

all, find, #names=, #slugs, #to_s

Class Method Details

.dataObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Array of hashes representing default atom properties.



12
13
14
# File 'lib/unitwise/atom.rb', line 12

def data
  @data ||= data_files.map { |file| YAML.load(File.open file) }.flatten
end

.data_filesObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Data files containing default atom data



18
19
20
# File 'lib/unitwise/atom.rb', line 18

def data_files
  %w(base_unit derived_unit).map { |type| Unitwise.data_file type }
end

Instance Method Details

#arbitrarytrue, false Also known as: arbitrary?

Determine if a unit is arbitrary. Arbitrary atoms are not of any specific dimension and have no general meaning, therefore cannot be compared with any other unit.

Returns:

  • (true, false)


62
63
64
# File 'lib/unitwise/atom.rb', line 62

def arbitrary
  !!@arbitrary
end

#base?true, false

Determine if an atom is base level. All atoms that are not base are defined directly or indirectly in reference to a base atom.

Returns:

  • (true, false)


27
28
29
# File 'lib/unitwise/atom.rb', line 27

def base?
  !!(@dim && !scale)
end

#depthInteger

Determine how far away a unit is from a base unit.

Returns:

  • (Integer)


70
71
72
# File 'lib/unitwise/atom.rb', line 70

def depth
  base? ? 0 : scale.depth + 1
end

#derived?true, false

Determine if an atom is derived. Derived atoms are defined with respect to other atoms.

Returns:

  • (true, false)


35
36
37
# File 'lib/unitwise/atom.rb', line 35

def derived?
  !base?
end

#dimString

A representation of an atoms composition. Used to determine if two different atoms are compatible.

Returns:

  • (String)


86
87
88
# File 'lib/unitwise/atom.rb', line 86

def dim
  terminal? ? @dim || property : composition_string
end

#magnitude(scalar = scalar()) ⇒ Object



109
110
111
# File 'lib/unitwise/atom.rb', line 109

def magnitude(scalar = scalar())
  special? ? scale.magnitude(scalar) : BigDecimal('1')
end

#metrictrue, false Also known as: metric?

Determine if an atom is metric. Metric atoms can be combined with metric prefixes.

Returns:

  • (true, false)


43
44
45
# File 'lib/unitwise/atom.rb', line 43

def metric
  base? ? true : !!@metric
end

#root_termsArray

An atom may have a complex scale with several base atoms at various depths. This method returns all of this atoms base level terms.

Returns:

  • (Array)

    An array containing base Unitwise::Term



116
117
118
# File 'lib/unitwise/atom.rb', line 116

def root_terms
  base? ? [Term.new(:atom_code => primary_code)] : scale.root_terms
end

#scalar(magnitude = 1) ⇒ Numeric

Get a numeric value that can be used to with other atoms to compare with or operate on. Base units have a scalar of 1.

Returns:

  • (Numeric)


105
106
107
# File 'lib/unitwise/atom.rb', line 105

def scalar(magnitude = 1)
  base? ? BigDecimal(magnitude.to_s) : scale.scalar(magnitude)
end

#scale=(attrs) ⇒ Unitwise::Functional, Unitwise::Scale

Set the atom's scale. It can be set as a Scale or a Functional



93
94
95
96
97
98
99
# File 'lib/unitwise/atom.rb', line 93

def scale=(attrs)
  @scale = if attrs[:function_code]
    Functional.new(attrs[:value], attrs[:unit_code], attrs[:function_code])
  else
    Scale.new(attrs[:value], attrs[:unit_code])
  end
end

#specialtrue, false Also known as: special?

Determine if a unit is special. Special atoms are not defined on a traditional ratio scale.

Returns:

  • (true, false)


52
53
54
# File 'lib/unitwise/atom.rb', line 52

def special
  !!@special
end

#terminal?true, false

Determine if this is the last atom in the scale chain

Returns:

  • (true, false)


78
79
80
# File 'lib/unitwise/atom.rb', line 78

def terminal?
  depth <= 3
end

#validate!true

A basic validator for atoms. It checks for the bare minimum properties and that it's scalar and magnitude can be resolved. Note that this method requires the units it depends on to already exist, so it is not used when loading the initial data from UCUM.

Returns:

  • (true)

    returns true if the atom is valid

Raises:



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/unitwise/atom.rb', line 128

def validate!
  missing_properties = %i{primary_code names scale}.select do |prop|
    val = liner_get(prop)
    val.nil? || (val.respond_to?(:empty) && val.empty?)
  end

  if !missing_properties.empty?
    missing_list = missing_properties.join(',')
    raise Unitwise::DefinitionError,
      "Atom has missing properties: #{missing_list}."
  end

  msg = "Atom definition could not be resolved. Ensure that it is a base " \
        "unit or is defined relative to existing units."

  begin
    !scalar.nil? && !magnitude.nil? || raise(Unitwise::DefinitionError, msg)
  rescue Unitwise::ExpressionError
    raise Unitwise::DefinitionError,  msg
  end
end