Class: SassC::Script::Value::Number
- Inherits:
-
SassC::Script::Value
- Object
- SassC::Script::Value
- SassC::Script::Value::Number
- Defined in:
- lib/sassc/script/value/number.rb
Overview
A SassScript object representing a number. SassScript numbers can have decimal values, and can also have units. For example, ‘12`, `1px`, and `10.45em` are all valid values.
Numbers can also have more complex units, such as ‘1px*em/in`. These cannot be inputted directly in Sass code at the moment.
Constant Summary collapse
- NO_UNITS =
Used so we don’t allocate two new arrays for each new number.
[]
Instance Attribute Summary collapse
-
#denominator_units ⇒ Array<String>
readonly
A list of units in the denominator of the number.
-
#numerator_units ⇒ Array<String>
readonly
A list of units in the numerator of the number.
-
#original ⇒ Boolean?
The original representation of this number.
-
#value ⇒ Numeric
readonly
The Ruby value of the number.
Attributes inherited from SassC::Script::Value
Class Method Summary collapse
-
.epsilon ⇒ Object
Used in checking equality of floating point numbers.
- .precision ⇒ Object
-
.precision=(digits) ⇒ Object
Sets the number of digits of precision For example, if this is ‘3`, `3.1415926` will be printed as `3.142`.
-
.precision_factor ⇒ Object
the precision factor used in numeric output it is derived from the ‘precision` method.
Instance Method Summary collapse
-
#coerce(num_units, den_units) ⇒ Number
Returns this number converted to other units.
-
#comparable_to?(other) ⇒ Boolean
Whether or not this number can be compared with the other.
-
#eql?(other) ⇒ Boolean
Hash-equality works differently than ‘==` equality for numbers.
- #hash ⇒ Object
-
#initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS) ⇒ Number
constructor
A new instance of Number.
-
#inspect(opts = {}) ⇒ String
(also: #to_sass)
Returns a readable representation of this number.
-
#int? ⇒ Boolean
Whether or not this number is an integer.
-
#is_unit?(unit) ⇒ Boolean
Checks whether the number has the numerator unit specified.
-
#legal_units? ⇒ Boolean
Whether or not this number has units that can be represented in CSS (that is, zero or one #numerator_units).
-
#to_i ⇒ Integer
The integer value of the number.
-
#to_s(opts = {}) ⇒ String
The CSS representation of this number.
-
#unit_str ⇒ String
Returns a human readable representation of the units in this number.
-
#unitless? ⇒ Boolean
Whether or not this number has no units.
Methods inherited from SassC::Script::Value
#==, #assert_int!, #bracketed, #null?, #separator, #to_a, #to_bool, #to_h, #with_contents
Constructor Details
#initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS) ⇒ Number
Returns a new instance of Number.
73 74 75 76 77 78 79 80 81 |
# File 'lib/sassc/script/value/number.rb', line 73 def initialize(value, numerator_units = NO_UNITS, denominator_units = NO_UNITS) numerator_units = [numerator_units] if numerator_units.is_a?(::String) denominator_units = [denominator_units] if denominator_units.is_a?(::String) super(value) @numerator_units = numerator_units @denominator_units = denominator_units @options = nil normalize! end |
Instance Attribute Details
#denominator_units ⇒ Array<String> (readonly)
A list of units in the denominator of the number. For example, ‘1px*em/in*cm` would return `[“in”, “cm”]`
27 28 29 |
# File 'lib/sassc/script/value/number.rb', line 27 def denominator_units @denominator_units end |
#numerator_units ⇒ Array<String> (readonly)
A list of units in the numerator of the number. For example, ‘1px*em/in*cm` would return `[“px”, “em”]`
22 23 24 |
# File 'lib/sassc/script/value/number.rb', line 22 def numerator_units @numerator_units end |
#original ⇒ Boolean?
The original representation of this number. For example, although the result of ‘1px/2px` is `0.5`, the value of `#original` is `“1px/2px”`.
This is only non-nil when the original value should be used as the CSS value, as in ‘font: 1px/2px`.
37 38 39 |
# File 'lib/sassc/script/value/number.rb', line 37 def original @original end |
#value ⇒ Numeric (readonly)
The Ruby value of the number.
17 18 19 |
# File 'lib/sassc/script/value/number.rb', line 17 def value @value end |
Class Method Details
.epsilon ⇒ Object
Used in checking equality of floating point numbers. Any numbers within an ‘epsilon` of each other are considered functionally equal. The value for epsilon is one tenth of the current numeric precision.
63 64 65 |
# File 'lib/sassc/script/value/number.rb', line 63 def self.epsilon Thread.current[:sass_numeric_epsilon] ||= 1 / (precision_factor * 10) end |
.precision ⇒ Object
39 40 41 |
# File 'lib/sassc/script/value/number.rb', line 39 def self.precision Thread.current[:sass_numeric_precision] || Thread.main[:sass_numeric_precision] || 10 end |
.precision=(digits) ⇒ Object
Sets the number of digits of precision For example, if this is ‘3`, `3.1415926` will be printed as `3.142`. The numeric precision is stored as a thread local for thread safety reasons. To set for all threads, be sure to set the precision on the main thread.
48 49 50 51 52 |
# File 'lib/sassc/script/value/number.rb', line 48 def self.precision=(digits) Thread.current[:sass_numeric_precision] = digits.round Thread.current[:sass_numeric_precision_factor] = nil Thread.current[:sass_numeric_epsilon] = nil end |
.precision_factor ⇒ Object
the precision factor used in numeric output it is derived from the ‘precision` method.
56 57 58 |
# File 'lib/sassc/script/value/number.rb', line 56 def self.precision_factor Thread.current[:sass_numeric_precision_factor] ||= 10.0**precision end |
Instance Method Details
#coerce(num_units, den_units) ⇒ Number
Returns this number converted to other units. The conversion takes into account the relationship between e.g. mm and cm, as well as between e.g. in and cm.
If this number has no units, it will simply return itself with the given units.
An incompatible coercion, e.g. between px and cm, will raise an error.
192 193 194 195 196 197 198 199 |
# File 'lib/sassc/script/value/number.rb', line 192 def coerce(num_units, den_units) Number.new(if unitless? value else value * coercion_factor(@numerator_units, num_units) / coercion_factor(@denominator_units, den_units) end, num_units, den_units) end |
#comparable_to?(other) ⇒ Boolean
Returns Whether or not this number can be compared with the other.
203 204 205 206 207 208 |
# File 'lib/sassc/script/value/number.rb', line 203 def comparable_to?(other) operate(other, :+) true rescue Sass::UnitConversionError false end |
#eql?(other) ⇒ Boolean
Hash-equality works differently than ‘==` equality for numbers. Hash-equality must be transitive, so it just compares the exact value, numerator units, and denominator units.
90 91 92 93 |
# File 'lib/sassc/script/value/number.rb', line 90 def eql?(other) basically_equal?(value, other.value) && numerator_units == other.numerator_units && denominator_units == other.denominator_units end |
#hash ⇒ Object
83 84 85 |
# File 'lib/sassc/script/value/number.rb', line 83 def hash [value, numerator_units, denominator_units].hash end |
#inspect(opts = {}) ⇒ String Also known as: to_sass
Returns a readable representation of this number.
This representation is valid CSS (and valid SassScript) as long as there is only one unit.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/sassc/script/value/number.rb', line 110 def inspect(opts = {}) return original if original value = self.class.round(self.value) str = value.to_s # Ruby will occasionally print in scientific notation if the number is # small enough. That's technically valid CSS, but it's not well-supported # and confusing. str = ("%0.#{self.class.precision}f" % value).gsub(/0*$/, '') if str.include?('e') # Sometimes numeric formatting will result in a decimal number with a trailing zero (x.0) if str =~ /(.*)\.0$/ str = $1 end # We omit a leading zero before the decimal point in compressed mode. if @options && [:style] == :compressed str.sub!(/^(-)?0\./, '\1.') end unitless? ? str : "#{str}#{unit_str}" end |
#int? ⇒ Boolean
Returns Whether or not this number is an integer.
143 144 145 |
# File 'lib/sassc/script/value/number.rb', line 143 def int? basically_equal?(value % 1, 0.0) end |
#is_unit?(unit) ⇒ Boolean
Checks whether the number has the numerator unit specified.
162 163 164 165 166 167 168 |
# File 'lib/sassc/script/value/number.rb', line 162 def is_unit?(unit) if unit denominator_units.size == 0 && numerator_units.size == 1 && numerator_units.first == unit else unitless? end end |
#legal_units? ⇒ Boolean
Returns Whether or not this number has units that can be represented in CSS (that is, zero or one #numerator_units).
172 173 174 |
# File 'lib/sassc/script/value/number.rb', line 172 def legal_units? (@numerator_units.empty? || @numerator_units.size == 1) && @denominator_units.empty? end |
#to_i ⇒ Integer
Returns The integer value of the number.
137 138 139 140 |
# File 'lib/sassc/script/value/number.rb', line 137 def to_i super unless int? value.to_i end |
#to_s(opts = {}) ⇒ String
Returns The CSS representation of this number.
98 99 100 101 102 |
# File 'lib/sassc/script/value/number.rb', line 98 def to_s(opts = {}) return original if original raise Sass::SyntaxError.new("#{inspect} isn't a valid CSS value.") unless legal_units? inspect end |
#unit_str ⇒ String
Returns a human readable representation of the units in this number. For complex units this takes the form of: numerator_unit1 * numerator_unit2 / denominator_unit1 * denominator_unit2
214 215 216 217 218 219 220 221 |
# File 'lib/sassc/script/value/number.rb', line 214 def unit_str rv = @numerator_units.sort.join("*") if @denominator_units.any? rv << "/" rv << @denominator_units.sort.join("*") end rv end |
#unitless? ⇒ Boolean
Returns Whether or not this number has no units.
148 149 150 |
# File 'lib/sassc/script/value/number.rb', line 148 def unitless? @numerator_units.empty? && @denominator_units.empty? end |