Class: Van::Units::Converter

Inherits:
Object
  • Object
show all
Defined in:
lib/van/units.rb,
lib/van/units/base.rb,
lib/van/units/loaders.rb,
lib/van/units/currency.rb,
lib/van/units_currency.rb

Overview

Load conversion units.

Defined Under Namespace

Classes: Conversion, ExchangeRate, ShiftedConversion

Constant Summary collapse

THREAD_REFERENCE =
'Units::converter'.to_sym

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Converter

Creates a new Converter. If a block is given, it is executed in the newly created Converter’s context.



668
669
670
671
672
# File 'lib/van/units/base.rb', line 668

def initialize(name)
  @conversions = {}
  @included = []
  @name = name
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &blk) ⇒ Object



729
730
731
732
733
734
735
736
737
# File 'lib/van/units/base.rb', line 729

def method_missing(m, *args, &blk)
  if registered?(m)
    raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
    return Units::Unit.new({m => 1}, self)
  end
  ::Exception.with_clean_backtrace("method_missing") {
    super
  }
end

Instance Attribute Details

#nameObject

Returns the name of this Converter, or nil if the Converter is not registered.



663
664
665
# File 'lib/van/units/base.rb', line 663

def name
  @name
end

Class Method Details

.coerce_units(unit1, unit2) ⇒ Object

:nodoc:



915
916
917
# File 'lib/van/units/base.rb', line 915

def coerce_units(unit1, unit2) # :nodoc:
  [convert_conversion(unit1.units), convert_conversion(unit2.units)]
end

.convert_conversion(units, multiplier = nil) ⇒ Object



924
925
926
927
928
929
930
931
932
933
934
935
936
# File 'lib/van/units/base.rb', line 924

def convert_conversion(units, multiplier = nil)
  multiplier ||= 1
  base_units = {}
  other_units = {}
  units.each_pair do |u, e|
    (u.conversion != :none ? other_units : base_units)[u] = e
  end
  result = Conversion.new(Units::Unit.new(base_units, self), multiplier)
  other_units.each_pair do |u, e|
    result *= (u.conversion ** e)
  end
  result
end

.converter(name, &blk) ⇒ Object

Returns the converter with the given name. This name can be a Symbol or a String.



889
890
891
892
893
894
895
# File 'lib/van/units/base.rb', line 889

def converter(name, &blk)
  if blk
    (converters[name.to_sym] ||= new(name.to_sym)).instance_eval(&blk)
  else
    converters[name.to_sym] or raise ::ArgumentError, "No converter #{name.to_s.dump} found"
  end
end

.convertersObject



938
939
940
# File 'lib/van/units/base.rb', line 938

def converters
  @converters ||= {}
end

.currentObject

Returns the current Converter in the current Thread. The default converter is the one returned by converter(:default). See also Units#with_converter and Converter.converter.



864
865
866
# File 'lib/van/units/base.rb', line 864

def current
  Thread.current[THREAD_REFERENCE] ||= converter(:default)
end

.register_loader(loader) ⇒ Object

def load(file)

  load_config(file, self)
end


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/van/units/loaders.rb', line 49

def register_loader(loader)
  loaders[loader] ||= loader
  loader.handles.each do |h|
    loader_hash[h] ||= begin
      eval %{
        module_eval do
          def #{h}(*a, &b)
            self.class.send(:loader_hash)[#{h.inspect}].#{h}(self, *a, &b)
          end
        end
      }
      loader
    end
  end
  @loader_hash
end

.registered_convertersObject

Returns the list of names of registered converters.



911
912
913
# File 'lib/van/units/base.rb', line 911

def registered_converters
  converters.keys
end

.require(file) ⇒ Object



38
39
40
41
42
43
# File 'lib/van/units/loaders.rb', line 38

def require(file)
  @required_configs[file] ||= begin
    load_config(file + ".rb", self)
    true
  end
end

.simplify_unit(unit) ⇒ Object

:nodoc:



919
920
921
922
# File 'lib/van/units/base.rb', line 919

def simplify_unit(unit) # :nodoc:
  conv = convert_conversion(unit.units)
  [conv[:multiplier], conv[:units]]
end

.with_converter(conv) ⇒ Object

:nodoc:

Raises:

  • (::ArgumentError)


868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
# File 'lib/van/units/base.rb', line 868

def with_converter(conv) # :nodoc:
  conv = converter(conv) if not conv.is_a? Units::Converter
  raise ::ArgumentError, "Converter expected" if not conv.is_a? Units::Converter
  begin
    old_conv = Thread.current[THREAD_REFERENCE]
    if old_conv
      new_conv = Converter.send(:new, nil)
      new_conv.include(old_conv)
      new_conv.include(conv)
    else
      new_conv = conv
    end
    Thread.current[THREAD_REFERENCE] = new_conv
    yield
  ensure
    Thread.current[THREAD_REFERENCE] = old_conv
  end
end

Instance Method Details

#base_unit(name) ⇒ Object

Returns the base unit with this name



716
717
718
719
720
721
# File 'lib/van/units/base.rb', line 716

def base_unit(name)
  if conv = registered?(name)
    return Units::BaseUnit.new(name, conv)
  end
  raise "unit #{name.to_s.dump} not registered with #{self}"
end

#include(conv) ⇒ Object

Included the given converter in the receiver, unless it was already included.



676
677
678
679
680
681
# File 'lib/van/units/base.rb', line 676

def include(conv)
  conv = Units::Converter.converter(conv) if not conv.is_a?(Units::Converter)
  raise "Circular include" if conv.includes?(self)
  @included << conv if not includes? conv
  self
end

#included_converters(result = []) ⇒ Object

Returns the list of all included converters. This list may contain duplicates in some cases.



696
697
698
699
700
# File 'lib/van/units/base.rb', line 696

def included_converters(result = [])
  result << self
  @included.reverse_each { |c| c.included_converters(result) }
  result
end

#includes?(conv) ⇒ Boolean

Returns whether the given converter was included in the receiver.

Returns:

  • (Boolean)


685
686
687
688
689
690
691
692
# File 'lib/van/units/base.rb', line 685

def includes?(conv)
  conv = Units::Converter.converter(conv) if not conv.is_a?(Units::Converter)
  return true if conv == self
  @included.each do |c|
    return true if conv == c || c.includes?(conv)
  end
  false
end

#load(file) ⇒ Object



83
84
85
# File 'lib/van/units/loaders.rb', line 83

def load(file)
  self.class.send(:load_config, file, self)
end

#registered?(unit) ⇒ Boolean

Checks whether the unit with the given name is registered. The name can be a symbol or a string.

Returns:

  • (Boolean)


704
705
706
707
708
709
710
711
712
713
# File 'lib/van/units/base.rb', line 704

def registered?(unit)
  unit = unit.to_sym
  return self if registered_here?(unit)
  @included.reverse_each do |c|
    if res = c.registered?(unit)
      return res
    end
  end
  nil
end

#registered_unitsObject

Returns the list of registered unit names as symbols.



724
725
726
# File 'lib/van/units/base.rb', line 724

def registered_units
  @conversions.keys
end

#to_sObject Also known as: inspect

Returns a human readable string representation of this Converter.



740
741
742
# File 'lib/van/units/base.rb', line 740

def to_s
  (@name.to_s if @name) || "#<Converter:#{object_id.to_s(16)}>"
end