Sha256: 4cdcfdc8f78e1d140147a81b1d9a5fb9a841f41cba04e15412911499a520271f

Contents?: true

Size: 1.58 KB

Versions: 2

Compression:

Stored size: 1.58 KB

Contents

require 'set'

class Measurement
  class Unit
    attr_reader :name, :aliases, :conversions
    
    @definitions = {}
    
    def initialize(name)
      @name = name.to_s
      @aliases = Set.new
      @conversions = {}
      add_alias(name)
    end
    
    def add_alias(*args)
      args.each do |unit_alias|
        @aliases << unit_alias.to_s
        self.class[unit_alias] = self
      end
    end
    
    def add_conversion(unit_name, &block)
      @conversions[unit_name.to_s] = block
    end
    
    def conversion(unit_name)
      unit = self.class[unit_name]
      return nil unless unit
      
      unit.aliases.each do |unit_alias|
        conversion = @conversions[unit_alias.to_s]
        return conversion if conversion
      end
      
      nil
    end
    
    def inspect
      to_s
    end
    
    def to_s
      name
    end
    
    def ==(obj)
      obj.kind_of?(self.class) && hash == obj.hash
    end
    
    def self.define(unit_name, &block)
      Builder.new(unit_name, &block)
    end
    
    def self.[](unit_name)
      @definitions[unit_name.to_s.downcase]
    end
    
    private
    
    def self.[]=(unit_name, unit)
      @definitions[unit_name.to_s.downcase] = unit
    end
    
    class Builder
      def initialize(unit_name, &block)
        @unit = Unit.new(unit_name)
        block.call(self) if block_given?
      end
      
      def alias(*args)
        @unit.add_alias(*args)
      end
      
      def convert_to(unit_name, &block)
        @unit.add_conversion(unit_name, &block)
      end
      
      def to_unit
        @unit
      end
    end
  end
end

Version data entries

2 entries across 2 versions & 1 rubygems

Version Path
ruby-measurement-1.2.0 lib/ruby-measurement/unit.rb
ruby-measurement-1.1.0 lib/ruby-measurement/unit.rb