Class: UnitMeasurements::Unit

Inherits:
Object
  • Object
show all
Defined in:
lib/unit_measurements/unit.rb

Overview

The UnitMeasurements::Unit class represents a unit of measurement and provides methods to interact with its properties and conversion factors.

Author:

Since:

  • 1.0.0

Constant Summary collapse

SI_BINARY_PREFIXES =

Binary prefixes for SI units.

Author:

Since:

  • 5.0.0

[
  ["Ki", %w[kibi], 2.pow(10)],
  ["Mi", %w[mebi], 2.pow(20)],
  ["Gi", %w[gibi], 2.pow(30)],
  ["Ti", %w[tebi], 2.pow(40)],
  ["Pi", %w[pebi], 2.pow(50)],
  ["Ei", %w[exbi], 2.pow(60)],
  ["Zi", %w[zebi], 2.pow(70)],
  ["Yi", %w[yobi], 2.pow(80)],
].map(&:freeze).freeze
SI_DECIMAL_PREFIXES =

Decimal prefixes for SI units.

Author:

Since:

  • 1.0.0

[
  ["q",  %w[quecto],    1e-30],
  ["r",  %w[ronto],     1e-27],
  ["y",  %w[yocto],     1e-24],
  ["z",  %w[zepto],     1e-21],
  ["a",  %w[atto],      1e-18],
  ["f",  %w[femto],     1e-15],
  ["p",  %w[pico],      1e-12],
  ["n",  %w[nano],      1e-9],
  ["μ",  %w[micro],     1e-6],
  ["m",  %w[milli],     1e-3],
  ["c",  %w[centi],     1e-2],
  ["d",  %w[deci],      1e-1],
  ["da", %w[deca deka], 1e+1],
  ["h",  %w[hecto],     1e+2],
  ["k",  %w[kilo],      1e+3],
  ["M",  %w[mega],      1e+6],
  ["G",  %w[giga],      1e+9],
  ["T",  %w[tera],      1e+12],
  ["P",  %w[peta],      1e+15],
  ["E",  %w[exa],       1e+18],
  ["Z",  %w[zetta],     1e+21],
  ["Y",  %w[yotta],     1e+24],
  ["R",  %w[ronna],     1e+27],
  ["Q",  %w[quetta],    1e+30]
].map(&:freeze).freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, value:, aliases:, system:, unit_group: nil) ⇒ Unit

Initializes a new Unit instance.

Parameters:

  • name (String|Symbol)

    The name of the unit.

  • value (String|Numeric)

    The conversion value of the unit.

  • aliases (Array<String|Symbol>)

    Alternative names for the unit.

  • system (String|Symbol|NilClass)

    The system to which the unit belongs.

  • unit_group (UnitGroup|NilClass) (defaults to: nil)

    The unit group to which the unit belongs.

Author:

Since:

  • 1.0.0



66
67
68
69
70
71
72
# File 'lib/unit_measurements/unit.rb', line 66

def initialize(name, value:, aliases:, system:, unit_group: nil)
  @name = name.to_s.freeze
  @value = value
  @aliases = Set.new(aliases.map(&:to_s).sort.map(&:freeze)).freeze
  @system = system.to_s.freeze
  @unit_group = unit_group
end

Instance Attribute Details

#aliasesSet<String> (readonly)

A set of alternative names for the unit.

Returns:

  • (Set<String>)

    A set of alternative names.

Author:

Since:

  • 1.0.0



38
39
40
# File 'lib/unit_measurements/unit.rb', line 38

def aliases
  @aliases
end

#nameString (readonly)

The name of the unit.

Returns:

  • (String)

    Name of the unit.

Author:

Since:

  • 1.0.0



20
21
22
# File 'lib/unit_measurements/unit.rb', line 20

def name
  @name
end

#systemString (readonly)

The system to which the unit belongs (e.g., “metric”, “imperial”).

Returns:

  • (String)

    Unit system in which the unit belongs.

Author:

Since:

  • 4.0.0



46
47
48
# File 'lib/unit_measurements/unit.rb', line 46

def system
  @system
end

#unit_groupUnitGroup (readonly)

The unit group to which the unit belongs.

Returns:

  • (UnitGroup)

    Unit group in which the unit belongs.

Author:

Since:

  • 1.0.0



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

def unit_group
  @unit_group
end

#valueString|Numeric|Array<Numeric, String> (readonly)

The conversion value of the unit. It can be a numeric value or a string in the form of a number followed by a unit name (e.g., “10 m”).

Returns:

  • (String|Numeric|Array<Numeric, String>)

    Conversion value of the unit.

Author:

Since:

  • 1.0.0



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

def value
  @value
end

Instance Method Details

#conversion_factorNumeric

Calculates the conversion factor for the unit. This method is recursively invoked to calculate the conversion factor of the unit, if unit conversion value is specified with respect to the other unit.

This method uses parse_value method to extract the conversion value and the unit.

Returns:

  • (Numeric)

    The conversion factor as a numeric value.

See Also:

Author:

Since:

  • 1.0.0



148
149
150
151
152
153
154
155
# File 'lib/unit_measurements/unit.rb', line 148

def conversion_factor
  return value if value.is_a?(Numeric)

  measurement_value, measurement_unit = parse_value(value)
  conversion_factor = unit_group.unit_for!(measurement_unit).conversion_factor

  conversion_factor * measurement_value
end

#inspectObject

Returns an object representation of the unit, including its aliases if present.

Returns:

  • (Object)

    An object representation of the unit.

Author:

Since:

  • 1.0.0



131
132
133
134
# File 'lib/unit_measurements/unit.rb', line 131

def inspect
  aliases = "(#{@aliases.join(", ")})" if @aliases.any?
  "#<#{self.class.name}: #{name} #{aliases}>"
end

#namesArray<String>

Returns an array containing the name of the unit and its aliases, sorted alphabetically.

Examples:

UnitMeasurements::Length.new(1, "m").unit.names
=> ["m", "meter", "meters", "metre", "metres"]

Returns:

  • (Array<String>)

    An array of unit names.

Author:

Since:

  • 1.0.0



107
108
109
# File 'lib/unit_measurements/unit.rb', line 107

def names
  (aliases + [name]).sort.freeze
end

#parse_value(tokens) ⇒ Array<Numeric, String> (private)

Parses tokens and returns a conversion value and the unit.

This method is used internally to parse the conversion value of the unit while calculating the conversion factor. It handles cases where the value can be provided as a string or an array containing a number and a unit.

For example, if the value is provided as a string in the form of “10 m”, it will be parsed to return 10.0 as the conversion value and “m” as the unit.

This method returns conversion value in rational number to avoid precision errors and frozen string of unit name.

Parameters:

  • tokens (String|Array)

    The value to be parsed. It can be either a string or an array containing a number and a unit.

Returns:

  • (Array<Numeric, String>)

    The array of conversion value and the unit.

Raises:

  • (BaseError)

    if tokens is not an instance of Array or String, or tokens array contains more than two elements.

See Also:

Author:

Since:

  • 1.2.0



231
232
233
234
235
236
237
238
239
240
241
# File 'lib/unit_measurements/unit.rb', line 231

def parse_value(tokens)
  case tokens
  when String
    tokens = Parser.parse(value)
  when Array
    raise BaseError, "Cannot parse [number, unit] formatted tokens from #{tokens}." unless tokens.size == 2
  else
    raise BaseError, "Value of the unit must be defined as string or array, but received #{tokens}"
  end
  [tokens[0].to_r, tokens[1].freeze]
end

#to_sString

Returns the name of the unit as a string.

Examples:

UnitMeasurements::Length.new(1, "m").unit.to_s
=> "m"

Returns:

  • (String)

    The name of the unit.

Author:

Since:

  • 1.0.0



121
122
123
# File 'lib/unit_measurements/unit.rb', line 121

def to_s
  name
end

#with(name: nil, value: nil, aliases: nil, system: nil, unit_group: nil) ⇒ Unit

Returns a new Unit instance with specified attributes.

Parameters:

  • name (String|Symbol) (defaults to: nil)

    The new name of the unit.

  • value (String|Numeric) (defaults to: nil)

    The new conversion value of the unit.

  • aliases (Set<String>) (defaults to: nil)

    New alternative names for the unit.

  • system (String|Symbol|NilClass) (defaults to: nil)

    The new system to which the unit belongs.

  • unit_group (UnitGroup|NilClass) (defaults to: nil)

    The new unit group to which the unit belongs.

Returns:

  • (Unit)

    A new unit with specified parameters.

Author:

Since:

  • 1.0.0



86
87
88
89
90
91
92
93
94
# File 'lib/unit_measurements/unit.rb', line 86

def with(name: nil, value: nil, aliases: nil, system: nil, unit_group: nil)
  self.class.new(
    (name || self.name),
    value: (value || self.value),
    aliases: (aliases || self.aliases),
    system: (system || self.system),
    unit_group: (unit_group || self.unit_group)
  )
end