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
15
16
17
18
19
20
# File 'lib/unitwise/atom.rb', line 12

def data
  @data ||= begin
    properties = data_files.map do |file|
      f = File.open(file)
      ::YAML.respond_to?(:unsafe_load) ? ::YAML.unsafe_load(f) : ::YAML.load(f)
    end
    properties.flatten
  end
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



24
25
26
# File 'lib/unitwise/atom.rb', line 24

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)


68
69
70
# File 'lib/unitwise/atom.rb', line 68

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)


33
34
35
# File 'lib/unitwise/atom.rb', line 33

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

#depthInteger

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

Returns:

  • (Integer)


76
77
78
# File 'lib/unitwise/atom.rb', line 76

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)


41
42
43
# File 'lib/unitwise/atom.rb', line 41

def derived?
  !base?
end

#dimString

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

Returns:

  • (String)


92
93
94
# File 'lib/unitwise/atom.rb', line 92

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

#magnitude(scalar = scalar()) ⇒ Object



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

def magnitude(scalar = scalar())
  special? ? scale.magnitude(scalar) : 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)


49
50
51
# File 'lib/unitwise/atom.rb', line 49

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



122
123
124
# File 'lib/unitwise/atom.rb', line 122

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)


111
112
113
# File 'lib/unitwise/atom.rb', line 111

def scalar(magnitude = 1)
  base? ? magnitude : 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



99
100
101
102
103
104
105
# File 'lib/unitwise/atom.rb', line 99

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)


58
59
60
# File 'lib/unitwise/atom.rb', line 58

def special
  !!@special
end

#terminal?true, false

Determine if this is the last atom in the scale chain

Returns:

  • (true, false)


84
85
86
# File 'lib/unitwise/atom.rb', line 84

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:



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/unitwise/atom.rb', line 134

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