Parent

Van::Units::Converter

This class handles all conversions between units.

There are two kinds of units; those that are not expressed as a function of other units —called base units— and those that are expressed as a function of other units —called derived units. The latter kind is registered specifying how it depends on other units, while the former kind is not.

This class also registers a list of Converters that are generally useable. The default Converter which is used when none is specified, can be retrieved with Converter.current. Converters can be registered with Converter.register.

Converters can be loaded from YAML. This allows Converters to be specified in configuration files.


Load conversion units.


Load conversion units.

Constants

ShiftedConversion
THREAD_REFERENCE

Attributes

name[RW]

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

Public Class Methods

register_loader(loader) click to toggle source

def load(file)

  load_config(file, self)

end

    # File lib/van/units/loaders.rb, line 49
49:       def register_loader(loader)
50:         loaders[loader] ||= loader
51:         loader.handles.each do |h|
52:           loader_hash[h] ||= begin
53:             eval %{
54:               module_eval do
55:                 def #{h}(*a, &b)
56:                   self.class.send(:loader_hash)[#{h.inspect}].#{h}(self, *a, &b)
57:                 end
58:               end
59:             }
60:             loader
61:           end
62:         end
63:         @loader_hash
64:       end
require(file) click to toggle source
    # File lib/van/units/loaders.rb, line 38
38:       def require(file)
39:         @required_configs[file] ||= begin
40:           load_config(file + ".rb", self)
41:           true
42:         end
43:       end

Private Class Methods

convert_conversion(units, multiplier = nil) click to toggle source
     # File lib/van/units/base.rb, line 924
924:       def convert_conversion(units, multiplier = nil)
925:         multiplier ||= 1
926:         base_units = {}
927:         other_units = {}
928:         units.each_pair do |u, e|
929:           (u.conversion != :none ? other_units : base_units)[u] = e
930:         end
931:         result = Conversion.new(Units::Unit.new(base_units, self), multiplier)
932:         other_units.each_pair do |u, e|
933:           result *= (u.conversion ** e)
934:         end
935:         result
936:       end
converter(name, &blk) click to toggle source

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

     # File lib/van/units/base.rb, line 889
889:       def converter(name, &blk)
890:         if blk
891:           (converters[name.to_sym] ||= new(name.to_sym)).instance_eval(&blk)
892:         else
893:           converters[name.to_sym] or raise ::ArgumentError, "No converter #{name.to_s.dump} found"
894:         end
895:       end
converters() click to toggle source
     # File lib/van/units/base.rb, line 938
938:       def converters
939:         @converters ||= {}
940:       end
current() click to toggle source

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.

     # File lib/van/units/base.rb, line 864
864:       def current
865:         Thread.current[THREAD_REFERENCE] ||= converter(:default)
866:       end
load_config(file, context) click to toggle source
    # File lib/van/units/loaders.rb, line 76
76:       def load_config(file, context)
77:         data = File.read(File.join(Units::Config::CONFIGDIR, file)) rescue File.read(file)
78:         context.instance_eval { eval data, nil, file }
79:       end
loader_hash() click to toggle source
    # File lib/van/units/loaders.rb, line 72
72:       def loader_hash
73:         @loader_hash ||= {}
74:       end
loaders() click to toggle source
    # File lib/van/units/loaders.rb, line 68
68:       def loaders
69:         @loaders ||= {}
70:       end
new(name) click to toggle source

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

     # File lib/van/units/base.rb, line 668
668:     def initialize(name)
669:       @conversions = {}
670:       @included = []
671:       @name = name
672:     end
registered_converters() click to toggle source

Returns the list of names of registered converters.

     # File lib/van/units/base.rb, line 911
911:       def registered_converters
912:         converters.keys
913:       end

Public Instance Methods

base_unit(name) click to toggle source

Returns the base unit with this name

     # File lib/van/units/base.rb, line 716
716:     def base_unit(name)
717:       if conv = registered?(name)
718:         return Units::BaseUnit.new(name, conv)
719:       end
720:       raise "unit #{name.to_s.dump} not registered with #{self}"
721:     end
include(conv) click to toggle source

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

     # File lib/van/units/base.rb, line 676
676:     def include(conv)
677:       conv = Units::Converter.converter(conv) if not conv.is_a?(Units::Converter)
678:       raise "Circular include" if conv.includes?(self)
679:       @included << conv if not includes? conv
680:       self
681:     end
included_converters(result = []) click to toggle source

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

     # File lib/van/units/base.rb, line 696
696:     def included_converters(result = [])
697:       result << self
698:       @included.reverse_each { |c| c.included_converters(result) }
699:       result
700:     end
includes?(conv) click to toggle source

Returns whether the given converter was included in the receiver.

     # File lib/van/units/base.rb, line 685
685:     def includes?(conv)
686:       conv = Units::Converter.converter(conv) if not conv.is_a?(Units::Converter)
687:       return true if conv == self
688:       @included.each do |c|
689:         return true if conv == c || c.includes?(conv)
690:       end
691:       false
692:     end
inspect() click to toggle source
Alias for: to_s
load(file) click to toggle source
    # File lib/van/units/loaders.rb, line 83
83:     def load(file)
84:       self.class.send(:load_config, file, self)
85:     end
method_missing(m, *args, &blk) click to toggle source
     # File lib/van/units/base.rb, line 729
729:     def method_missing(m, *args, &blk)
730:       if registered?(m)
731:         raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
732:         return Units::Unit.new({m => 1}, self)
733:       end
734:       ::Exception.with_clean_backtrace("method_missing") {
735:         super
736:       }
737:     end
registered?(unit) click to toggle source

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

     # File lib/van/units/base.rb, line 704
704:     def registered?(unit)
705:       unit = unit.to_sym
706:       return self if registered_here?(unit)
707:       @included.reverse_each do |c|
708:         if res = c.registered?(unit)
709:           return res
710:         end
711:       end
712:       nil
713:     end
registered_units() click to toggle source

Returns the list of registered unit names as symbols.

     # File lib/van/units/base.rb, line 724
724:     def registered_units
725:       @conversions.keys
726:     end
to_s() click to toggle source

Returns a human readable string representation of this Converter.

     # File lib/van/units/base.rb, line 740
740:     def to_s
741:       (@name.to_s if @name) || "#<Converter:#{object_id.to_s(16)}>"
742:     end
Also aliased as: inspect

Private Instance Methods

conversions(unit) click to toggle source
     # File lib/van/units/base.rb, line 851
851:     def conversions(unit)
852:       @conversions[unit] #|| (unit == :'--base-currency--' ? :none : nil)
853:     end
conversions(unit) click to toggle source
     # File lib/van/units/currency.rb, line 147
147:     def conversions(unit)
148:       @conversions[unit] || (unit == '--base-currency--'.to_sym ? :none : nil)
149:     end
decode_conversion(data) click to toggle source
     # File lib/van/units/base.rb, line 824
824:     def decode_conversion(data)
825:       if not data.is_a? ::String
826:         return {:unit => data[:unit] || data['unit'],
827:                 :multiplier => data[:multiplier] || data['multiplier']}
828:       end
829:       if /^\s*1\s*\// =~ data
830:         {:unit => Units::Unit.new(data, self)}
831:       elsif m = /^\s*#{Units::Regexps::NUMBER_REGEXP}(?:\s+(\S.*)$|\s*$)/.match(data)
832:         unit = m[3] ? Units::Unit.new(m[3], self) : Units::Unit.new({}, self)
833:         if m[1]
834:           multiplier = m[2].empty? ? Integer(m[1]) : Float(m[1])
835:           {:unit => unit, :multiplier => multiplier}
836:         else
837:           {:unit => unit}
838:         end
839:       else
840:         {:unit => Units::Unit.new(data, self)}
841:       end
842:     end
register_prefixed_unit(unit, prefixes, abbrevs=[], aliases=[], &conversion) click to toggle source
     # File lib/van/units/base.rb, line 796
796:     def register_prefixed_unit(unit, prefixes, abbrevs=[], aliases=[], &conversion)
797:       unit = unit.to_s
798:       abbrevs = [abbrevs].flatten.map{ |a| a.to_s }
799:       aliases = [aliases].flatten.map{ |a| a.to_s }
800:       aliases = ["#{unit}s"] if aliases.empty?
801:       #aliases, abbrevs = extract_data(unit, data, :to_s)
802:       register_unit(unit, abbrevs, aliases, &conversion)
803:       unit_sym = unit.to_sym
804:       prefixes.each_pair do |pre,info|
805:         abbrev     = info[:abbrev]
806:         multiplier = info[:multiplier] || 1
807:         power      = info[:power] || 1
808:         register_unit(pre + unit) do
809:           {:unit => Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier}
810:         end
811:         aliases.each do |a|
812:           register_unit(pre + a) do
813:             {:unit => Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier}
814:           end
815:         end
816:         abbrevs.each do |a|
817:           register_unit(abbrev + a) do
818:             {:unit => Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier}
819:           end
820:         end
821:       end
822:     end
register_unit(unit, abbrevs=[], aliases=[], &conversion) click to toggle source

Registers a new Unit with the given name. The data parameter is a Hash with some extra parameters (can be Strings or Symbols):

alias

Specifies possible aliases for the Unit.

abbrev

Specifies possible abbreviations or symbols for the Unit. The differences with aliases is that prefixes work differently; see register_si_unit, register_binary_unit and register_binary_iec_unit.

equals

If present, specifies how the Unit depends on other units. The value for this key can either be a Hash with unit mapping to a Unit and multiplier mapping to a numeric multiplier, or a String containing the multiplier, followed by a space, followed by a representation of the Unit as returned by Unit#to_s.

Examples:

  converter.register_unit(:pint, :alias => :pints, :abbrev => [:pt, :pts]))
  converter.register_unit(:quart, 'alias' => :quarts, :abbrev => ['qt', :qts], :equals => '2.0 pt'))
  converter.register_unit(:gallon, :alias => :gallons, :abbrev => :gal, 'equals' => {:unit => Unit.new('qt' => 1, converter), 'multiplier' => 4.0))

Note that Symbols and Strings are generally exchangeable within this library (internally they are converted to Symbols). The number one reason for this is that String look better in YAML.

See also register_si_unit, register_binary_unit, register_binary_iec_unit, register_length_unit, and register_currency in currency.rb.

     # File lib/van/units/base.rb, line 773
773:     def register_unit(unit, abbrevs=[], aliases=[], &conversion)
774:       unit    = unit.to_sym
775:       abbrevs = [abbrevs].flatten.map{ |a| a.to_sym }
776:       aliases = [aliases].flatten.map{ |a| a.to_sym }
777:       #aliases = ["#{unit}s".to_sym] if aliases.empty? # TRANS: hmm... not here?
778:       #unit, aliases, abbrevs = extract_data(name, data, :to_sym)
779:       #conversion = data[:equals]
780:       # TRANS: this can be imporved now that conversion is a block?
781:       conversion = conversion.call if conversion
782:       conversion = decode_conversion(conversion) if conversion
783:       conversion = self.class.convert_conversion(conversion[:unit].units, conversion[:multiplier]) if conversion
784:       register_unit_internal(unit, conversion)
785:       conversion = self.class.convert_conversion({base_unit(unit) => 1}, 1) if not conversion
786:       (aliases + abbrevs).each do |u|
787:         register_unit_internal(u, conversion)
788:       end
789:     end
register_unit_internal(unit, conversion) click to toggle source
     # File lib/van/units/base.rb, line 791
791:     def register_unit_internal(unit, conversion)
792:       raise "unit #{unit.to_s.dump} already registered with #{self}" if registered_here? unit
793:       @conversions[unit] = conversion || :none
794:     end
registered_here?(unit) click to toggle source

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

     # File lib/van/units/base.rb, line 846
846:     def registered_here?(unit)
847:       unit = unit.to_sym
848:       conversions(unit) != nil
849:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.