Sha256: a97d7abf0502824990c0a444367da77c10239a6707ab34b50ff625ed1c2a0686

Contents?: true

Size: 1.79 KB

Versions: 1

Compression:

Stored size: 1.79 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) && name == obj.name && aliases == obj.aliases && conversions.all? do |key, proc|
        [-2.5, -1, 0, 1, 2.5].all? { |n| proc.call(n) == obj.conversions[key].call(n) }
      end
    end
    
    def self.define(unit_name, &block)
      Builder.new(unit_name, &block)
    end
    
    def self.[](unit_name)
      @definitions[unit_name.to_s.downcase]
    end
    
    def self.names
      @definitions.keys
    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

1 entries across 1 versions & 1 rubygems

Version Path
ruby-measurement-1.2.2 lib/ruby-measurement/unit.rb