lib/conversions.rb in conversions-0.1.0 vs lib/conversions.rb in conversions-1.4.3

- old
+ new

@@ -1,46 +1,59 @@ -module UnitConversions - UNITS = ['kg', 'g', 't', 'mm2', 'm2'] - CONVERT_TO_PATTERN = /(#{UNITS.join('|')})_to_(#{UNITS.join('|')})/ - CONVERSIONS = { - 'kg' => { - 't' => lambda() {|kg| kg / 1000.0 }, - 'g' => lambda() {|kg| kg * 1000 }, - }, - 'g' => { - 'kg' => lambda() {|g| g / 1000.0}, - 't' => lambda() {|g| g / (1000.0 * 1000) }, - }, - 't' => { - 'kg' => lambda() {|t| t * 1000}, - 'g' => lambda() {|t| t * (1000 * 1000)}, - }, - 'm2' => { - 'mm2' => lambda() {|m2| m2 * (1000 * 1000.0)}, - }, - 'mm2' => { - 'm2' => lambda() {|mm2| mm2 / (1000 * 1000.0)}, - }, - } +# Conversions makes it easy to convert between units. +module Conversions + mattr_accessor :conversions + + # Clear all previously registered conversions + def self.clear + self.conversions = {} + end + clear - - def method_missing_with_unit_conversions(m, *args) - if args.length == 0 - m.to_s =~ CONVERT_TO_PATTERN - return CONVERSIONS[$1][$2].call(self) if CONVERSIONS[$1] && CONVERSIONS[$1][$2] + # Load all the default conversions shipped with the code + def self.load_defaults + load File.expand_path('../conversions/defaults.rb', __FILE__) + end + + # Register a new conversion. This automatically also registers the inverse conversion. + # + # * _from_: The unit to convert from (ie. :miles, :stones, or :pints) + # * _to_: The unit to convert to + # * _rate_: The conversion rate from _from_ to _to_. (_from_ * _rate_ = _to_) + def self.register(from, to, rate) + conversions[from] ||= {} + conversions[from][to] = rate + conversions[to] ||= {} + conversions[to][from] = 1.0 / rate + Conversions.define_shortcut(from) + Conversions.define_shortcut(to) + end + + def self.define_shortcut(unit) + Numeric.class_eval do + define_method unit do + Conversions::Unit.new(self, unit) + end unless respond_to? unit end - method_missing_without_unit_conversions(m, args) end - -end -class Fixnum - include UnitConversions - alias :method_missing_without_unit_conversions :method_missing - alias :method_missing :method_missing_with_unit_conversions + module Ext + # Convert from one unit to another. + # + # * _from_: The unit to convert from (ie. :miles, :stones, or :pints) + # * _to_: The unit to convert to + # * _options_: + # * :scale: The number of digits you want after the dot. + def convert(from, to, options={}) + Conversions::Unit.new(self, from).to(to, options) + end + end end -class Float - include UnitConversions - alias :method_missing_without_unit_conversions :method_missing - alias :method_missing :method_missing_with_unit_conversions +require 'conversions/unit' + +Conversions.load_defaults +Numeric.send(:include, Conversions::Ext) + +if defined?(ActiveRecord) + require 'conversions/active_record_accessors' + ActiveRecord::Base.send(:extend, Conversions::ActiveRecordAccessors) end \ No newline at end of file