lib/measured/unit.rb in measured-2.0.0.pre2 vs lib/measured/unit.rb in measured-2.0.0.pre3

- old
+ new

@@ -1,64 +1,73 @@ class Measured::Unit include Comparable - attr_reader :name, :names, :conversion_amount, :conversion_unit, :unit_system + attr_reader :name, :aliases, :conversion_amount, :conversion_unit, :unit_system def initialize(name, aliases: [], value: nil, unit_system: nil) - @name = name.to_s - @names = ([@name] + aliases.map(&:to_s)).sort + @name = name.to_s.freeze + @aliases = aliases.map(&:to_s).map(&:freeze).freeze @conversion_amount, @conversion_unit = parse_value(value) if value @unit_system = unit_system end def with_unit_system(unit_system) self.class.new( name, - aliases: names - [name], + aliases: aliases, value: conversion_string, unit_system: unit_system ) end + def names + @names ||= ([name] + aliases).sort!.freeze + end + def to_s - if conversion_string - "#{ @name } (#{ conversion_string })" + @to_s ||= if conversion_string + "#{name} (#{conversion_string})".freeze else - @name + name end end def inspect - "#<Measured::Unit: #{ @name } (#{ @names.join(", ") }) #{ conversion_string }>" + @inspect ||= begin + pieces = [name] + pieces << "(#{aliases.join(", ")})" if aliases.any? + pieces << conversion_string if conversion_string + "#<#{self.class.name}: #{pieces.join(" ")}>".freeze + end end def <=>(other) if self.class == other.class - names_comparison = @names <=> other.names + names_comparison = names <=> other.names if names_comparison != 0 names_comparison else - @conversion_amount <=> other.conversion_amount + conversion_amount <=> other.conversion_amount end else - @name <=> other + name <=> other end end def inverse_conversion_amount - 1 / conversion_amount.to_r + @inverse_conversion_amount ||= 1 / conversion_amount end private def conversion_string - "#{ conversion_amount } #{ conversion_unit }" if @conversion_amount || @conversion_unit + @conversion_string ||= ("#{conversion_amount} #{conversion_unit}" if conversion_amount || conversion_unit) end def parse_value(tokens) - tokens = tokens.split(" ") if tokens.is_a?(String) + tokens = tokens.split(" ", 2) if tokens.is_a?(String) raise Measured::UnitError, "Cannot parse 'number unit' or [number, unit] formatted tokens from #{tokens}." unless tokens.size == 2 - [tokens[0].to_r, tokens[1]] + [tokens[0].to_r, tokens[1].freeze] end end