lib/stick/units/base.rb in stick-1.3.1 vs lib/stick/units/base.rb in stick-1.3.2
- old
+ new
@@ -67,38 +67,37 @@
# K C F R D N R R
#
# http://en.wikipedia.org/wiki/Conversion_of_units
#++
-module Stick
module Units
def method_missing(m, *args, &blk)
if args.length == 1
- args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
- return ::Stick::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
- elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
+ args[0] = (::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Units::Converter
+ return ::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
+ elsif (::Units::Converter.current.registered?(m) rescue false)
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
- return ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current)
+ return ::Units::Unit.new({m => 1}, ::Units::Converter.current)
end
::Exception.with_clean_backtrace("method_missing") {
super
}
end
def const_missing(c)
- if (::Stick::Units::Converter.current.registered?(c) rescue false)
- return ::Stick::Units::Unit.new({c => 1}, ::Stick::Units::Converter.current)
+ if (::Units::Converter.current.registered?(c) rescue false)
+ return ::Units::Unit.new({c => 1}, ::Units::Converter.current)
else
::Exception.with_clean_backtrace("const_missing") {
super
}
end
end
def self.append_features(m)
- m.send(:extend, ::Stick::Units)
+ m.send(:extend, ::Units)
super
end
# Executes the block with the current Converter changed to
# the given Converter. This allows to temporarily change the
@@ -115,11 +114,11 @@
# puts 1.cwt.to(lb) # => 100.0 lb
# }
#
# See also Converter.current.
def with_unit_converter(name, &blk) # :yields:
- ::Stick::Units::Converter.with_converter(name, &blk)
+ ::Units::Converter.with_converter(name, &blk)
end
module_function :with_unit_converter
class Regexps
@@ -136,11 +135,11 @@
class BaseUnit
attr_reader :name, :converter
- def initialize(name, converter = ::Stick::Units::Converter.current)
+ def initialize(name, converter = ::Units::Converter.current)
name = name.to_sym
raise ::ArgumentError, "unit #{name.to_s.dump} not registered with #{converter}" if not converter.registered? name
@name = name
@converter = converter
end
@@ -148,21 +147,21 @@
def conversion
@converter.send(:conversions, @name)
end
def ==(other)
- other.is_a?(::Stick::Units::BaseUnit) && other.name == @name && other.converter == @converter
+ other.is_a?(::Units::BaseUnit) && other.name == @name && other.converter == @converter
end
alias eql? ==
def hash
@name.hash ^ @converter.hash
end
def to_s
- if ::Stick::Units::Converter.current.includes?(converter)
+ if ::Units::Converter.current.includes?(converter)
@name.to_s
else
"#{@converter}:#{@name}"
end
end
@@ -170,17 +169,17 @@
alias inspect to_s
end
# This class represents a Unit. A Unit uses a given Converter with
- # a number of registered Stick in which it can be expressed.
- # A Unit is the product of the powers of other Stick. In principle, these
+ # a number of registered units in which it can be expressed.
+ # A Unit is the product of the powers of other units. In principle, these
# need not be integer powers, but this may cause problems with rounding.
# The following code for example returns +false+:
# Unit.new(:m => 0.1) * Unit.new(:m => 0.2) == Unit.new(:m => 0.3)
#
- # Stick can be multiplied, divided, and raised to a given power.
+ # Units can be multiplied, divided, and raised to a given power.
# As an extra, 1 can be divided by a Unit.
#
# Examples:
#
# Unit.new(:mi => 1, :s => -1) ** 2 # => mi**2/s**2
@@ -201,17 +200,17 @@
# Unit.new(:m => 1, :s => -1, Converter.converter(:uk)) # => m/s
# Unit.new(:mi => 1, :s => -2) # => mi/s**2
#
# See also Converter, Converter.converter
def initialize(units = {}, converter = nil)
- conv = proc { converter ||= ::Stick::Units::Converter.current }
+ conv = proc { converter ||= ::Units::Converter.current }
if units.is_a? ::String
@units = decode_string(units, conv)
else
@units = {}
units.each_pair do |k, v|
- k = conv[].base_unit(k.to_sym) if not k.is_a? ::Stick::Units::BaseUnit
+ k = conv[].base_unit(k.to_sym) if not k.is_a? ::Units::BaseUnit
@units[k] = v
end
end
normalize_units
end
@@ -220,11 +219,11 @@
def **(p)
result = {}
@units.each_pair do |u, e|
result[u] = e * p
end
- ::Stick::Units::Unit.new(result)
+ ::Units::Unit.new(result)
end
# Multiplies with the given Unit.
def *(other)
do_op(:*, :+, other)
@@ -239,22 +238,22 @@
def unitless?
@units.empty?
end
def coerce(other) # :nodoc:
- return [::Stick::Units::Unit.new({}), self] if other == 1
- ::Stick::Units::Converter.coerce_units(self, other)
+ return [::Units::Unit.new({}), self] if other == 1
+ ::Units::Converter.coerce_units(self, other)
end
def simplify
- ::Stick::Units::Converter.simplify_unit(self)
+ ::Units::Converter.simplify_unit(self)
end
# Returns +true+ iff the two units are equals, <i>i.e.,</i> iff they have
# the same exponent for all units, and they both use the same Converter.
def ==(other)
- other.is_a?(::Stick::Units::Unit) && other.units == units
+ other.is_a?(::Units::Unit) && other.units == units
end
alias eql? ==
def hash
@@ -263,11 +262,11 @@
# Returns +true+ iff this Unit is compatible with the given
# Unit. This is less strict than equality because for example hours are
# compatible with seconds ("we can add them"), but hours are not seconds.
def compatible_with?(other)
- conv1, conv2 = ::Stick::Units::Converter.coerce_units(self, other)
+ conv1, conv2 = ::Units::Converter.coerce_units(self, other)
conv1.units == conv2.units
end
# Returns a human readable string representation.
def to_s
@@ -287,25 +286,25 @@
alias inspect to_s
def method_missing(m, *args, &blk)
if args.length == 1
- args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
- return self * ::Stick::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
- elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
+ args[0] = (::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Units::Converter
+ return self * ::Units::Unit.new({m => 1}, args[0]) if args[0] && args[0].registered?(m)
+ elsif (::Units::Converter.current.registered?(m) rescue false)
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
- return self * ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current)
+ return self * ::Units::Unit.new({m => 1}, ::Units::Converter.current)
end
::Exception.with_clean_backtrace("method_missing") {
super
}
end
private
def decode_string(s, converter)
- if ::Stick::Units::Regexps::TOTAL_UNIT_REGEXP =~ s
+ if ::Units::Regexps::TOTAL_UNIT_REGEXP =~ s
numerator, denominator = $1, $2
units = {}
decode_multiplicative_string(numerator, 1, converter, units) if numerator
decode_multiplicative_string(denominator, -1, converter, units) if denominator
units
@@ -315,13 +314,13 @@
raise ::ArgumentError, "Illegal unit string #{s.dump}"
end
end
def decode_multiplicative_string(s, multiplier, converter, result)
- s.scan(::Stick::Units::Regexps::SINGLE_UNIT_REGEXP) do |conv, unit, exp|
+ s.scan(::Units::Regexps::SINGLE_UNIT_REGEXP) do |conv, unit, exp|
if unit
- conv = ::Stick::Units::Converter.converter(conv)
+ conv = ::Units::Converter.converter(conv)
else
conv, unit = converter[], conv
end
exp ||= '1'
unit = conv.base_unit(unit)
@@ -335,17 +334,17 @@
end
end
def do_op(op, dual_op, other)
other = other.to_unit
- raise TypeError, "cannot convert to Unit" unless ::Stick::Units::Unit === other
+ raise TypeError, "cannot convert to Unit" unless ::Units::Unit === other
result = @units.dup
other.units.each_pair do |u, e|
result[u] = 0 if not result[u]
result[u] = result[u].send(dual_op, e)
end
- ::Stick::Units::Unit.new(result)
+ ::Units::Unit.new(result)
end
end
# This class represents a Value with a numeric value and a Unit.
@@ -412,26 +411,26 @@
end
%w{ * / }.each do |op|
eval %{
def #{op}(other)
- ::Stick::Units::Value.new(*do_multiplicative_op(:#{op}, other))
+ ::Units::Value.new(*do_multiplicative_op(:#{op}, other))
end
}
end
%w{ + - modulo remainder % }.each do |op|
eval %{
def #{op}(other)
- ::Stick::Units::Value.new(*do_additive_op(:#{op}, other))
+ ::Units::Value.new(*do_additive_op(:#{op}, other))
end
}
end
def divmod(other)
(q, r), unit = *do_additive_op(:divmod, other)
- [q, ::Stick::Units::Value.new(r, unit)]
+ [q, ::Units::Value.new(r, unit)]
end
def div(other)
do_additive_op(:div, other)[0]
end
@@ -443,11 +442,11 @@
def +@ # :nodoc:
self
end
def **(other) # :nodoc:
- ::Stick::Units::Value.new(@value ** other, @unit ** other)
+ ::Units::Value.new(@value ** other, @unit ** other)
end
def <=>(other) # :nodoc:
if other == 0
@value <=> 0
@@ -465,11 +464,11 @@
end
%w{ abs ceil floor next round succ truncate }.each do |op|
eval %{
def #{op}
- ::Stick::Units::Value.new(@value.#{op}, @unit)
+ ::Units::Value.new(@value.#{op}, @unit)
end
}
end
%w{ finite? infinite? integer? nan? nonzero? zero? }.each do |op|
@@ -485,20 +484,20 @@
# and the given Unit are the same. It obviously fails if the
# Units are not compatible (can't add apples and oranges).
def to(to_unit, converter = nil)
raise ArgumentError, "Wrong number of arguments" if converter && !(::String === to_unit)
to_unit = to_unit.to_unit(converter)
- raise TypeError, "cannot convert to Unit" unless ::Stick::Units::Unit === to_unit
+ raise TypeError, "cannot convert to Unit" unless ::Units::Unit === to_unit
conv1, conv2 = unit.coerce(to_unit)
raise TypeError, "incompatible units for operation" if conv1.units != conv2.units
mult = conv1.multiplier / conv2.multiplier
- ::Stick::Units::Value.new(value * mult, to_unit)
+ ::Units::Value.new(value * mult, to_unit)
end
def coerce(other) # :nodoc:
if ::Numeric === other
- [::Stick::Units::Value.new!(other, ::Stick::Units::Unit.new), self]
+ [::Units::Value.new!(other, ::Units::Unit.new), self]
else
super
end
end
@@ -509,33 +508,33 @@
# Returns a float if this Value is unitless, and raises an
# exception otherwise.
def to_f
val = simplify
- if ::Stick::Units::Value === val
+ if ::Units::Value === val
raise TypeError, "Cannot convert to float"
else
val.to_f
end
end
# Returns an int if this Value is unitless, and raises an
# exception otherwise.
def to_i
val = simplify
- if ::Stick::Units::Value === val
+ if ::Units::Value === val
raise TypeError, "Cannot convert to integer"
else
val.to_i
end
end
# Returns an int if this Value is unitless, and raises an
# exception otherwise.
def to_int
val = simplify
- if ::Stick::Units::Value === val
+ if ::Units::Value === val
raise TypeError, "Cannot convert to integer"
else
val.to_int
end
end
@@ -545,11 +544,11 @@
def simplify
mul, new_unit = *@unit.simplify
if new_unit.unitless?
@value * mul
else
- ::Stick::Units::Value.new(@value * mul, new_unit)
+ ::Units::Value.new(@value * mul, new_unit)
end
end
# Returns +self+.
def to_value(converter = nil)
@@ -558,37 +557,37 @@
alias inspect to_s
def method_missing(m, *args, &blk)
if args.length == 1
- args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
- return self * ::Stick::Units::Value.new(1, ::Stick::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
- elsif (::Stick::Units::Converter.current.registered?(m) rescue false)
+ args[0] = (::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Units::Converter
+ return self * ::Units::Value.new(1, ::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
+ elsif (::Units::Converter.current.registered?(m) rescue false)
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
- return self * ::Stick::Units::Value.new(1, ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current))
+ return self * ::Units::Value.new(1, ::Units::Unit.new({m => 1}, ::Units::Converter.current))
end
::Exception.with_clean_backtrace("method_missing") {
super
}
end
private
def self.decode_string(s, converter)
- if m = ::Stick::Units::Regexps::VALUE_REGEXP.match(s)
+ if m = ::Units::Regexps::VALUE_REGEXP.match(s)
value = m[2].empty? ? Integer(m[1]) : Float(m[1])
- unit = ::Stick::Units::Unit.new(m[3], converter)
+ unit = ::Units::Unit.new(m[3], converter)
[value, unit]
else
raise ::ArgumentError, "Illegal value string #{s.dump}"
end
end
def do_additive_op(op, other)
other = other.to_value
- raise TypeError, "cannot convert to Value" unless ::Stick::Units::Value === other
- if other.is_a? ::Stick::Units::Value
+ raise TypeError, "cannot convert to Value" unless ::Units::Value === other
+ if other.is_a? ::Units::Value
conv1, conv2 = unit.coerce(other.unit)
raise TypeError, "incompatible units for #{op}" if conv1.units != conv2.units
mult = conv2.multiplier / conv1.multiplier
if mult > 1
[value.send(op, other.value * mult), unit]
@@ -601,22 +600,22 @@
end
end
def do_multiplicative_op(op, other)
case other
- when ::Stick::Units::Value
+ when ::Units::Value
[value.send(op, other.value), unit.send(op, other.unit)]
- when ::Stick::Units::Unit
+ when ::Units::Unit
[value, unit.send(op, other)]
when ::Numeric
[value.send(op, other), unit]
else
- # TODO: How to make this work for Stick as well?
+ # TODO: How to make this work for Units as well?
# Problem : how check whether to_value failed without
# masking all exceptions?
other = other.to_value
- raise TypeError, "cannot convert to Value" unless ::Stick::Units::Value === other
+ raise TypeError, "cannot convert to Value" unless ::Units::Value === other
do_multiplicative_op(op, other)
end
end
end
@@ -671,20 +670,20 @@
end
# Included the given converter in the receiver, unless it
# was already included.
def include(conv)
- conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::Units::Converter)
+ 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
# Returns whether the given converter was included in the
# receiver.
def includes?(conv)
- conv = ::Stick::Units::Converter.converter(conv) if not conv.is_a?(::Stick::Units::Converter)
+ 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
@@ -712,11 +711,11 @@
end
# Returns the base unit with this name
def base_unit(name)
if conv = registered?(name)
- return ::Stick::Units::BaseUnit.new(name, conv)
+ return ::Units::BaseUnit.new(name, conv)
end
raise "unit #{name.to_s.dump} not registered with #{self}"
end
# Returns the list of registered unit names as symbols.
@@ -726,11 +725,11 @@
#
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)
+ return ::Units::Unit.new({m => 1}, self)
end
::Exception.with_clean_backtrace("method_missing") {
super
}
end
@@ -792,16 +791,16 @@
unit_sym = unit.to_sym
prefixes.each_pair do |pre,info|
abbrev = info[:abbrev]
multiplier = info[:multiplier] || 1
power = info[:power] || 1
- register_unit(pre + unit, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
+ register_unit(pre + unit, :equals => {:unit => ::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
aliases.each do |a|
- register_unit(pre + a, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
+ register_unit(pre + a, :equals => {:unit => ::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
end
abbrevs.each do |a|
- register_unit(abbrev + a, :equals => {:unit => ::Stick::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
+ register_unit(abbrev + a, :equals => {:unit => ::Units::Unit.new({unit_sym => power}, self), :multiplier => multiplier})
end
end
end
def extract_data(unit, data, conv)
@@ -818,21 +817,21 @@
if not data.is_a? ::String
return {:unit => data[:unit] || data['unit'],
:multiplier => data[:multiplier] || data['multiplier']}
end
if /^\s*1\s*\// =~ data
- {:unit => ::Stick::Units::Unit.new(data, self)}
- elsif m = /^\s*#{::Stick::Units::Regexps::NUMBER_REGEXP}(?:\s+(\S.*)$|\s*$)/.match(data)
- unit = m[3] ? ::Stick::Units::Unit.new(m[3], self) : ::Stick::Units::Unit.new({}, self)
+ {:unit => ::Units::Unit.new(data, self)}
+ elsif m = /^\s*#{::Units::Regexps::NUMBER_REGEXP}(?:\s+(\S.*)$|\s*$)/.match(data)
+ unit = m[3] ? ::Units::Unit.new(m[3], self) : ::Units::Unit.new({}, self)
if m[1]
multiplier = m[2].empty? ? Integer(m[1]) : Float(m[1])
{:unit => unit, :multiplier => multiplier}
else
{:unit => unit}
end
else
- {:unit => ::Stick::Units::Unit.new(data, self)}
+ {:unit => ::Units::Unit.new(data, self)}
end
end
# Checks whether the unit with the given name is registered.
# The name can be a symbol or a string.
@@ -845,35 +844,37 @@
@conversions[unit] #|| (unit == :'--base-currency--' ? :none : nil)
end
class << self
+ THREAD_REFERENCE = 'Units::converter'.to_sym
+
private :new
# Returns the current Converter in the current Thread.
# The default converter is the one returned by <code>converter(:default)</code>.
- # See also Stick::Units#with_converter and Converter.converter.
+ # See also Units#with_converter and Converter.converter.
def current
- Thread.current[:'Stick::Units::converter'] ||= converter(:default)
+ Thread.current[THREAD_REFERENCE] ||= converter(:default)
end
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
+ 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[:'Stick::Units::converter']
+ 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[:'Stick::Units::converter'] = new_conv
+ Thread.current[THREAD_REFERENCE] = new_conv
yield
ensure
- Thread.current[:'Stick::Units::converter'] = old_conv
+ Thread.current[THREAD_REFERENCE] = old_conv
end
end
# Returns the converter with the given name.
# This name can be a Symbol or a String.
@@ -917,11 +918,11 @@
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)
+ result = Conversion.new(::Units::Unit.new(base_units, self), multiplier)
other_units.each_pair do |u, e|
result *= (u.conversion ** e)
end
result
end
@@ -942,40 +943,39 @@
SYSTEMDIR = File.dirname(__FILE__)
CONFIGDIR = File.join(SYSTEMDIR, 'data')
end
end
-end
class Numeric
#
def method_missing(m, *args, &blk)
if args.length == 1
- args[0] = (::Stick::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Stick::Units::Converter
- return ::Stick::Units::Value.new(self, ::Stick::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
- elsif ::Stick::Units::Converter.current.registered?(m)
+ args[0] = (::Units::Converter.converter(args[0]) rescue nil) if not args[0].is_a? ::Units::Converter
+ return ::Units::Value.new(self, ::Units::Unit.new({m => 1}, args[0])) if args[0] && args[0].registered?(m)
+ elsif ::Units::Converter.current.registered?(m)
raise ::ArgumentError, "Wrong number of arguments" if args.length != 0
- return ::Stick::Units::Value.new(self, ::Stick::Units::Unit.new({m => 1}, ::Stick::Units::Converter.current))
+ return ::Units::Value.new(self, ::Units::Unit.new({m => 1}, ::Units::Converter.current))
end
::Exception.with_clean_backtrace("method_missing") {
super
}
end
#
def to_value(unit)
- ::Stick::Units::Value.new(self, unit)
+ ::Units::Value.new(self, unit)
end
end
class String
#
def to_unit(converter = nil)
- ::Stick::Units::Unit.new(self, converter)
+ ::Units::Unit.new(self, converter)
end
#
def to_value(converter = nil)
- ::Stick::Units::Value.new(self, converter)
+ ::Units::Value.new(self, converter)
end
end