Class: Unit::System

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) {|_self| ... } ⇒ System

Returns a new instance of System.

Yields:

  • (_self)

Yield Parameters:

  • _self (Unit::System)

    the object that the method was called on



8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# File 'lib/unit/system.rb', line 8

def initialize(name)
  @name = name
  @unit = {}
  @unit_symbol = {}

  # one is internal trivial factor
  @factor = {one: {symbol: 'one', value: 1} }
  @factor_symbol = {'one' => :one}
  @factor_value = {1 => :one}

  @loaded_systems = []
  @loaded_filenames = []

  yield(self) if block_given?
end

Instance Attribute Details

#factorObject (readonly)

Returns the value of attribute factor.



6
7
8
# File 'lib/unit/system.rb', line 6

def factor
  @factor
end

#factor_symbolObject (readonly)

Returns the value of attribute factor_symbol.



6
7
8
# File 'lib/unit/system.rb', line 6

def factor_symbol
  @factor_symbol
end

#factor_valueObject (readonly)

Returns the value of attribute factor_value.



6
7
8
# File 'lib/unit/system.rb', line 6

def factor_value
  @factor_value
end

#nameObject (readonly)

Returns the value of attribute name.



6
7
8
# File 'lib/unit/system.rb', line 6

def name
  @name
end

#unitObject (readonly)

Returns the value of attribute unit.



6
7
8
# File 'lib/unit/system.rb', line 6

def unit
  @unit
end

#unit_symbolObject (readonly)

Returns the value of attribute unit_symbol.



6
7
8
# File 'lib/unit/system.rb', line 6

def unit_symbol
  @unit_symbol
end

Instance Method Details

#load(input) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/unit/system.rb', line 24

def load(input)
  case input
  when Hash
    data = input
  when IO
    data = YAML.load(input.read)
  when String
    if File.exist?(input)
      return if @loaded_filenames.include?(input)
      data = YAML.load_file(input)
      @loaded_filenames << input
    else
      load(input.to_sym)
      return
    end
  when Symbol
    return if @loaded_systems.include?(input)
    data = YAML.load_file(File.join(File.dirname(__FILE__), 'systems', "#{input}.yml"))
    @loaded_systems << input
  end

  load_factors(data['factors']) if data['factors']
  load_units(data['units']) if data['units']

  @unit.each {|name, unit| validate_unit(unit[:def]) }

  true
end

#parse_unit(expr) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/unit/system.rb', line 63

def parse_unit(expr)
  stack, result, implicit_mul = [], [], false
  expr.to_s.scan(TOKENIZER).each do |tok|
    if tok == '('
      stack << '('
      implicit_mul = false
    elsif tok == ')'
      compute(result, stack.pop) while !stack.empty? && stack.last != '('
      raise(SyntaxError, 'Unexpected token )') if stack.empty?
      stack.pop
      implicit_mul = true
    elsif OPERATOR.key?(tok)
      compute(result, stack.pop) while !stack.empty? && stack.last != '(' && OPERATOR[stack.last][1] >= OPERATOR[tok][1]
      stack << OPERATOR[tok][0]
      implicit_mul = false
    else
      val = case tok
            when REAL   then [[:one, tok.to_f, 1]]
            when DEC    then [[:one, tok.to_i, 1]]
            when SYMBOL then symbol_to_unit(tok)
            end
      stack << '*' if implicit_mul
      implicit_mul = true
      result << val
    end
  end
  compute(result, stack.pop) while !stack.empty?
  result.last
end

#validate_unit(units) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/unit/system.rb', line 53

def validate_unit(units)
  units.each do |factor, unit, exp|
    #raise TypeError, 'Factor must be symbol' if !(Symbol === factor)
    #raise TypeError, 'Unit must be symbol' if !(Numeric === unit || Symbol === unit)
    #raise TypeError, 'Exponent must be numeric' if !(Numeric === exp)
    raise TypeError, "Undefined factor #{factor}" if !@factor[factor]
    raise TypeError, "Undefined unit #{unit}" if !(Numeric === unit || @unit[unit])
  end
end