<file_sep>require './model/length'
require './model/weight'

public

  def method_missing(method, *args, &block)
    val = method[-1] == 's' ? method : "#{method}s" # Поддержка единственного и множественного наименования метода
    condition(val.to_sym)
  end

private

  # Условие вывода результата
  def condition(method)
    if Length::STANDARTS.include?(method)
      Length.new(self, method)
    elsif Weight::STANDARTS.include?(method)
      Weight.new(self, method)
    else
      raise NoMethodError, "undefined method #{method}"
    end
  end
<file_sep>class Weight < Length

  # Конвертирующие коэффициенты
  STANDARTS = {
    kilograms: 1,
    gramms: 1000,
    pounds: 2.205,
    ounces: 35.2739619
  }

end<file_sep>class Length

  require './model/error'

  # Конвертирующие коэффициенты
  STANDARTS = {
    meters: 1,
    miles: 0.000621371192,
    inches: 39.3700787,
    centimeters: 100
  }

  # Инициализация переменных
  def initialize(num, type)
    @num = num
    @type = type
  end

  # Конвертация одной велечины в другую
  def in(val)
    standarts = self.class::STANDARTS # выбор констант в зависимости от класса
    error(@type, val) unless standarts.include?(val) # вывод ошибки
    @num * ( standarts[val] / standarts[@type] )
  end

  # Ошибка конвертации разных типов велечин
  def error(type, value)
    raise TypeMismatch, "impossible to convert #{type} per #{value}"
  end

end<file_sep>class TypeMismatch < Exception; end