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