Class: Stick::Units::Converter
- Inherits:
-
Object
- Object
- Stick::Units::Converter
- Defined in:
- lib/stick/units.rb,
lib/stick/currency.rb,
lib/stick/units/base.rb,
lib/stick/units/loaders.rb,
lib/stick/units/currency.rb
Overview
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.
Defined Under Namespace
Classes: Conversion, ExchangeRate, ShiftedConversion
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the name of this Converter, or
nil
if the Converter is not registered.
Class Method Summary collapse
-
.coerce_units(unit1, unit2) ⇒ Object
:nodoc:.
- .convert_conversion(units, multiplier = nil) ⇒ Object
-
.converter(name, &blk) ⇒ Object
Returns the converter with the given name.
- .converters ⇒ Object
-
.current ⇒ Object
Returns the current Converter in the current Thread.
-
.register_loader(loader) ⇒ Object
def load(file) load_config(file, self) end.
-
.registered_converters ⇒ Object
Returns the list of names of registered converters.
- .require(file) ⇒ Object
-
.simplify_unit(unit) ⇒ Object
:nodoc:.
-
.with_converter(conv) ⇒ Object
:nodoc:.
Instance Method Summary collapse
-
#base_unit(name) ⇒ Object
Returns the base unit with this name.
-
#include(conv) ⇒ Object
Included the given converter in the receiver, unless it was already included.
-
#included_converters(result = []) ⇒ Object
Returns the list of all included converters.
-
#includes?(conv) ⇒ Boolean
Returns whether the given converter was included in the receiver.
-
#initialize(name) ⇒ Converter
constructor
Creates a new Converter.
- #load(file) ⇒ Object
- #method_missing(m, *args, &blk) ⇒ Object
-
#registered?(unit) ⇒ Boolean
Checks whether the unit with the given name is registered.
-
#registered_units ⇒ Object
Returns the list of registered unit names as symbols.
-
#to_s ⇒ Object
(also: #inspect)
Returns a human readable string representation of this Converter.
Constructor Details
#initialize(name) ⇒ Converter
Creates a new Converter. If a block is given, it is executed in the newly created Converter’s context.
667 668 669 670 671 |
# File 'lib/stick/units/base.rb', line 667 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
728 729 730 731 732 733 734 735 736 |
# File 'lib/stick/units/base.rb', line 728 def method_missing(m, *args, &blk) if registered?(m) raise ::ArgumentError, "Wrong number of arguments" if args.length != 0 return ::Stick::Units::Unit.new({m => 1}, self) end ::Exception.with_clean_backtrace("method_missing") { super } end |
Instance Attribute Details
#name ⇒ Object
Returns the name of this Converter, or nil
if the Converter is not registered.
662 663 664 |
# File 'lib/stick/units/base.rb', line 662 def name @name end |
Class Method Details
.coerce_units(unit1, unit2) ⇒ Object
:nodoc:
906 907 908 |
# File 'lib/stick/units/base.rb', line 906 def coerce_units(unit1, unit2) # :nodoc: [convert_conversion(unit1.units), convert_conversion(unit2.units)] end |
.convert_conversion(units, multiplier = nil) ⇒ Object
915 916 917 918 919 920 921 922 923 924 925 926 927 |
# File 'lib/stick/units/base.rb', line 915 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(::Stick::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.
880 881 882 883 884 885 886 |
# File 'lib/stick/units/base.rb', line 880 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 |
.converters ⇒ Object
929 930 931 |
# File 'lib/stick/units/base.rb', line 929 def converters @converters ||= {} end |
.current ⇒ Object
Returns the current Converter in the current Thread. The default converter is the one returned by converter(:default)
. See also Stick::Units#with_converter and Converter.converter.
855 856 857 |
# File 'lib/stick/units/base.rb', line 855 def current Thread.current[:'Stick::Units::converter'] ||= 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/stick/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_converters ⇒ Object
Returns the list of names of registered converters.
902 903 904 |
# File 'lib/stick/units/base.rb', line 902 def registered_converters converters.keys end |
.require(file) ⇒ Object
38 39 40 41 42 43 |
# File 'lib/stick/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:
910 911 912 913 |
# File 'lib/stick/units/base.rb', line 910 def simplify_unit(unit) # :nodoc: conv = convert_conversion(unit.units) [conv[:multiplier], conv[:units]] end |
.with_converter(conv) ⇒ Object
:nodoc:
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 |
# File 'lib/stick/units/base.rb', line 859 def with_converter(conv) # :nodoc: conv = converter(conv) if not conv.is_a? ::Stick::Units::Converter raise ::ArgumentError, "Converter expected" if not conv.is_a? ::Stick::Units::Converter begin old_conv = Thread.current[:'Stick::Units::converter'] 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[:'Stick::Units::converter'] = new_conv yield ensure Thread.current[:'Stick::Units::converter'] = old_conv end end |
Instance Method Details
#base_unit(name) ⇒ Object
Returns the base unit with this name
715 716 717 718 719 720 |
# File 'lib/stick/units/base.rb', line 715 def base_unit(name) if conv = registered?(name) return ::Stick::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.
675 676 677 678 679 680 |
# File 'lib/stick/units/base.rb', line 675 def include(conv) conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::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.
695 696 697 698 699 |
# File 'lib/stick/units/base.rb', line 695 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.
684 685 686 687 688 689 690 691 |
# File 'lib/stick/units/base.rb', line 684 def includes?(conv) conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::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/stick/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.
703 704 705 706 707 708 709 710 711 712 |
# File 'lib/stick/units/base.rb', line 703 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_units ⇒ Object
Returns the list of registered unit names as symbols.
723 724 725 |
# File 'lib/stick/units/base.rb', line 723 def registered_units @conversions.keys end |
#to_s ⇒ Object Also known as: inspect
Returns a human readable string representation of this Converter.
739 740 741 |
# File 'lib/stick/units/base.rb', line 739 def to_s (@name.to_s if @name) || "#<Converter:#{object_id.to_s(16)}>" end |