class Sass::Value::Number

def ==(other)

Returns:
  • (::Boolean) -
def ==(other)
  return false unless other.is_a?(Sass::Value::Number)
  return false if numerator_units.length != other.numerator_units.length ||
                  denominator_units.length != other.denominator_units.length
  return FuzzyMath.equals(value, other.value) if unitless?
  if Unit.canonicalize_units(numerator_units) != Unit.canonicalize_units(other.numerator_units) &&
     Unit.canonicalize_units(denominator_units) != Unit.canonicalize_units(other.denominator_units)
    return false
  end
  FuzzyMath.equals(
    (value *
    Unit.canonical_multiplier(numerator_units) /
    Unit.canonical_multiplier(denominator_units)),
    (other.value *
    Unit.canonical_multiplier(other.numerator_units) /
    Unit.canonical_multiplier(other.denominator_units))
  )
end

def assert_between(min, max, name = nil)

Raises:
  • (ScriptError) -

Returns:
  • (Numeric) -

Parameters:
  • max (Numeric) --
  • min (Numeric) --
def assert_between(min, max, name = nil)
  FuzzyMath.assert_between(value, min, max, name)
end

def assert_integer(name = nil)

Raises:
  • (ScriptError) -

Returns:
  • (Integer) -
def assert_integer(name = nil)
  raise Sass::ScriptError.new("#{self} is not an integer", name) unless integer?
  to_i
end

def assert_number(_name = nil)

Returns:
  • (Number) -
def assert_number(_name = nil)
  self
end

def assert_unit(unit, name = nil)

Raises:
  • (ScriptError) -

Returns:
  • (Number) -

Parameters:
  • unit (::String) --
def assert_unit(unit, name = nil)
  raise Sass::ScriptError.new("Expected #{self} to have unit #{unit.inspect}", name) unless unit?(unit)
  self
end

def assert_unitless(name = nil)

Raises:
  • (ScriptError) -

Returns:
  • (Number) -
def assert_unitless(name = nil)
  raise Sass::ScriptError.new("Expected #{self} to have no units", name) unless unitless?
  self
end

def canonical_units_value

def canonical_units_value
  if unitless?
    value
  elsif single_unit?
    value * Unit.canonical_multiplier_for_unit(numerator_units.first)
  else
    value * Unit.canonical_multiplier(numerator_units) / Unit.canonical_multiplier(denominator_units)
  end
end

def coerce(new_numerator_units, new_denominator_units, name = nil)

Returns:
  • (Number) -

Parameters:
  • new_denominator_units (Array<::String>) --
  • new_numerator_units (Array<::String>) --
def coerce(new_numerator_units, new_denominator_units, name = nil)
  Number.new(coerce_value(new_numerator_units, new_denominator_units, name), {
               numerator_units: new_numerator_units,
               denominator_units: new_denominator_units
             })
end

def coerce_or_convert_value(new_numerator_units, new_denominator_units,

def coerce_or_convert_value(new_numerator_units, new_denominator_units,
                            coerce_unitless:,
                            name: nil,
                            other: nil,
                            other_name: nil)
  if other && (other.numerator_units != new_denominator_units && other.denominator_units != new_denominator_units)
    raise Sass::ScriptError, "Expect #{other} to have units #{unit_string(new_numerator_units,
                                                                          new_denominator_units).inspect}"
  end
  return value if numerator_units == new_numerator_units && denominator_units == new_denominator_units
  return value if numerator_units == new_numerator_units && denominator_units == new_denominator_units
  other_unitless = new_numerator_units.empty? && new_denominator_units.empty?
  return value if coerce_unitless && (unitless? || other_unitless)
  compatibility_error = lambda {
    unless other.nil?
      message = "#{self} and"
      message << " $#{other_name}:" unless other_name.nil?
      message << " #{other} have incompatible units"
      message << " (one has units and the other doesn't)" if unitless? || other_unitless
      return Sass::ScriptError.new(message, name)
    end
    return Sass::ScriptError.new("Expected #{self} to have no units", name) unless other_unitless
    if new_numerator_units.length == 1 && new_denominator_units.empty?
      type = Unit::TYPES_BY_UNIT[new_numerator_units.first]
      return Sass::ScriptError.new(
        "Expected #{self} to have a #{type} unit (#{Unit::UNITS_BY_TYPE[type].join(', ')})", name
      )
    end
    unit_length = new_numerator_units.length + new_denominator_units.length
    units = unit_string(new_numerator_units, new_denominator_units)
    Sass::ScriptError.new("Expected #{self} to have unit#{unit_length > 1 ? 's' : ''} #{units}", name)
  }
  result = value
  old_numerator_units = numerator_units.dup
  new_numerator_units.each do |new_numerator_unit|
    index = old_numerator_units.find_index do |old_numerator_unit|
      factor = Unit.conversion_factor(new_numerator_unit, old_numerator_unit)
      if factor.nil?
        false
      else
        result *= factor
        true
      end
    end
    raise compatibility_error.call if index.nil?
    old_numerator_units.delete_at(index)
  end
  old_denominator_units = denominator_units.dup
  new_denominator_units.each do |new_denominator_unit|
    index = old_denominator_units.find_index do |old_denominator_unit|
      factor = Unit.conversion_factor(new_denominator_unit, old_denominator_unit)
      if factor.nil?
        false
      else
        result /= factor
        true
      end
    end
    raise compatibility_error.call if index.nil?
    old_denominator_units.delete_at(index)
  end
  raise compatibility_error.call unless old_numerator_units.empty? && old_denominator_units.empty?
  result
end

def coerce_to_match(other, name = nil, other_name = nil)

Returns:
  • (Number) -

Parameters:
  • other (Number) --
def coerce_to_match(other, name = nil, other_name = nil)
  Number.new(coerce_value_to_match(other, name, other_name), {
               numerator_units: other.numerator_units,
               denominator_units: other.denominator_units
             })
end

def coerce_value(new_numerator_units, new_denominator_units, name = nil)

Returns:
  • (Numeric) -

Parameters:
  • new_denominator_units (Array<::String>) --
  • new_numerator_units (Array<::String>) --
def coerce_value(new_numerator_units, new_denominator_units, name = nil)
  coerce_or_convert_value(new_numerator_units, new_denominator_units,
                          coerce_unitless: true,
                          name:)
end

def coerce_value_to_match(other, name = nil, other_name = nil)

Returns:
  • (Numeric) -

Parameters:
  • other (Number) --
def coerce_value_to_match(other, name = nil, other_name = nil)
  coerce_or_convert_value(other.numerator_units, other.denominator_units,
                          coerce_unitless: true,
                          name:,
                          other:,
                          other_name:)
end

def coerce_value_to_unit(unit, name = nil)

Returns:
  • (Numeric) -

Parameters:
  • unit (::String) --
def coerce_value_to_unit(unit, name = nil)
  coerce_value([unit], [], name)
end

def compatible_with_unit?(unit)

Returns:
  • (::Boolean) -

Parameters:
  • unit (::String) --
def compatible_with_unit?(unit)
  single_unit? && !Unit.conversion_factor(numerator_units.first, unit).nil?
end

def convert(new_numerator_units, new_denominator_units, name = nil)

Returns:
  • (Number) -

Parameters:
  • new_denominator_units (Array<::String>) --
  • new_numerator_units (Array<::String>) --
def convert(new_numerator_units, new_denominator_units, name = nil)
  Number.new(convert_value(new_numerator_units, new_denominator_units, name), {
               numerator_units: new_numerator_units,
               denominator_units: new_denominator_units
             })
end

def convert_to_match(other, name = nil, other_name = nil)

Returns:
  • (Number) -

Parameters:
  • other (Number) --
def convert_to_match(other, name = nil, other_name = nil)
  Number.new(convert_value_to_match(other, name, other_name), {
               numerator_units: other.numerator_units,
               denominator_units: other.denominator_units
             })
end

def convert_value(new_numerator_units, new_denominator_units, name = nil)

Returns:
  • (Numeric) -

Parameters:
  • new_denominator_units (Array<::String>) --
  • new_numerator_units (Array<::String>) --
def convert_value(new_numerator_units, new_denominator_units, name = nil)
  coerce_or_convert_value(new_numerator_units, new_denominator_units,
                          coerce_unitless: false,
                          name:)
end

def convert_value_to_match(other, name = nil, other_name = nil)

Returns:
  • (Numeric) -

Parameters:
  • other (Number) --
def convert_value_to_match(other, name = nil, other_name = nil)
  coerce_or_convert_value(other.numerator_units, other.denominator_units,
                          coerce_unitless: false,
                          name:,
                          other:,
                          other_name:)
end

def hash

Returns:
  • (Integer) -
def hash
  @hash ||= FuzzyMath._hash(canonical_units_value).hash
end

def initialize(value, unit = nil)

Options Hash: (**unit)
  • :denominator_units (Array<::String>) --
  • :numerator_units (Array<::String>) --

Parameters:
  • unit (::String, Hash) --
  • value (Numeric) --
def initialize(value, unit = nil)
  case unit
  when nil
    numerator_units = []
    denominator_units = []
  when ::String
    numerator_units = [unit]
    denominator_units = []
  when ::Hash
    numerator_units = unit.fetch(:numerator_units, [])
    unless numerator_units.is_a?(Array)
      raise Sass::ScriptError, "invalid numerator_units #{numerator_units.inspect}"
    end
    denominator_units = unit.fetch(:denominator_units, [])
    unless denominator_units.is_a?(Array)
      raise Sass::ScriptError, "invalid denominator_units #{denominator_units.inspect}"
    end
  else
    raise Sass::ScriptError, "invalid unit #{unit.inspect}"
  end
  unless denominator_units.empty? && numerator_units.empty?
    value = value.dup
    numerator_units = numerator_units.dup
    new_denominator_units = []
    denominator_units.each do |denominator_unit|
      index = numerator_units.find_index do |numerator_unit|
        factor = Unit.conversion_factor(denominator_unit, numerator_unit)
        if factor.nil?
          false
        else
          value *= factor
          true
        end
      end
      if index.nil?
        new_denominator_units.push(denominator_unit)
      else
        numerator_units.delete_at(index)
      end
    end
    denominator_units = new_denominator_units
  end
  @value = value.freeze
  @numerator_units = numerator_units.each(&:freeze).freeze
  @denominator_units = denominator_units.each(&:freeze).freeze
end

def integer?

Returns:
  • (::Boolean) -
def integer?
  FuzzyMath.integer?(value)
end

def single_unit?

def single_unit?
  numerator_units.length == 1 && denominator_units.empty?
end

def to_i

Returns:
  • (Integer) -
def to_i
  FuzzyMath.to_i(value)
end

def unit?(unit)

Returns:
  • (::Boolean) -

Parameters:
  • unit (::String) --
def unit?(unit)
  single_unit? && numerator_units.first == unit
end

def unit_string(numerator_units, denominator_units)

def unit_string(numerator_units, denominator_units)
  if numerator_units.empty?
    return 'no units' if denominator_units.empty?
    return denominator_units.length == 1 ? "#{denominator_units.first}^-1" : "(#{denominator_units.join('*')})^-1"
  end
  return numerator_units.join('*') if denominator_units.empty?
  "#{numerator_units.join('*')}/#{denominator_units.join('*')}"
end

def unitless?

Returns:
  • (::Boolean) -
def unitless?
  numerator_units.empty? && denominator_units.empty?
end

def units?

Returns:
  • (::Boolean) -
def units?
  !unitless?
end