Class: DYI::Length
Overview
This class representing a length. Length object holds an amount and a unit. The lists of unit identifiers matches the list of unit identifiers in CSS: em, ex, px, pt, pc, cm, mm, in and percentages(%). When a unit is not given, then the length is assumed to be in user units (i.e., a value in the current user coordinate sytem).
-
As in CSS, the em and ex unit identifiers are relative to the current font’s font-size and x-height, respectively.
-
One px unit is defined to be equal to one user unit.
-
1pt equals 1.25 user units.
-
1pc equals 15 user units.
-
1mm equals 3.543307 user units.
-
1cm equals 35.43307 user units.
-
1in equals 90 user units.
-
For percentage values that are defined to be relative to the size of parent element.
Distuptive Change
Length is not possible to change destructively. #clone
method and #dup
method raise TypeError.
Ways of Comparing and Calculating
This class includes Comparable
module, therefore you can use the comparative operators. In the comparison between DYI::Length objects, the unit of each objects are arranged and it compares. The equality operator ‘==
’ does not test equality instance but test equality value.
DYI::Length.new('1in') > DYI::Length.new(50) # => true, 1in equals 90px.
DYI::Length.new('1in') > DYI::Length.new('2em') # => Error, 'em' is not comparable unit.
DYI::Length.new('10cm') == DYI::Length.new('100mm') # => true
This class suports following arithmetic operators and methods: , -, *, /, %, **, #div, #quo, #modulo. The operators ‘+’, ‘-’ coerces a right hand operand into Length, and then calculates.
Constant Summary collapse
- UNITS =
Array of unit that can be used.
['px', 'pt', '%', 'cm', 'mm', 'in', 'em', 'ex', 'pc']
- ZERO =
Zero length.
new(0)
- @@units =
{'px'=>1.0,'pt'=>1.25,'cm'=>35.43307,'mm'=>3.543307,'in'=>90.0,'pc'=>15.0}
- @@default_format =
'0.###U'
Class Method Summary collapse
-
.default_format ⇒ String
Returns a format that is used when called #to_s without an argument.
-
.default_format=(fromat) ⇒ Object
Sets a format string that is used when called #to_s.
-
.new(*args) ⇒ Length
Creates and returns a new instance of Length provided the argument is not an instace of Length.
-
.new_or_nil(*args) ⇒ Length?
Returns a new instace of Length if the argments is not
nil
(callsLength.new
method), but returnsnil
if the argument isnil
. -
.set_default_format(format) ⇒ Object
Invokes block with given format string as default format.
-
.unit_ratio(unit) ⇒ Float
Returns a coefficient that is used for conversion from unit into user unit.
Instance Method Summary collapse
-
#%(other) ⇒ Number
(also: #modulo)
Return a number which is the modulo after division of the receiver by other.
-
#*(number) ⇒ Length
Returns a new muliplicative length of the receiver by number.
-
#**(number) ⇒ Length
Raises a length the number power.
-
#+(other) ⇒ Length
Returns a new length which is the sum of the receiver and other.
-
#+@ ⇒ Length
Unary Plus – Returns the receiver’s value.
-
#-(other) ⇒ Length
Returns a new length which is the difference of the receiver and other.
-
#-@ ⇒ Length
Unary Minus – Returns the receiver’s value, negated.
-
#/(number) ⇒ Object
(also: #quo)
Divisional operator.
-
#<=>(other) ⇒ Fixnum?
Comparision – compares two values.
-
#abs ⇒ Length
Returns the absolute length of the receiver.
- #clone ⇒ Object
-
#div(other) ⇒ Number
Returns a number which is the result of dividing the receiver by other.
- #dup ⇒ Object
-
#initialize(length) ⇒ Length
constructor
A new instance of Length.
- #inspect ⇒ Object
-
#nonzero? ⇒ Length?
Returns whether the receiver is a no-zero length.
-
#step(limit, step) ⇒ Object
Invokes block with the sequence of length starting at receiver.
-
#to_f(unit = nil) ⇒ Float
Returns amount part of the length converted into given unit as float.
-
#to_s(format = nil) ⇒ Length
Returns a string to represent the receiver.
-
#to_user_unit ⇒ Length
Returns a length that converted into length of user unit.
-
#unit ⇒ String
Returns the receiver’s unit.
-
#zero? ⇒ Boolean
Returns whether the receiver is a zero length.
Constructor Details
#initialize(length) ⇒ Length #initialize(num) ⇒ Length #initialize(str) ⇒ Length
Returns a new instance of Length.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/dyi/length.rb', line 85 def initialize(length) case length when Length @value = length._num @unit = length._unit when Numeric @value = length @unit = nil when String unless /^\s*(-?[\d]*(?:\d\.|\.\d|\d)[0\d]*)(#{UNITS.join('|')})?\s*$/ =~ length raise ArgumentError, "`#{length}' is string that could not be understand" end __value, __unit = $1, $2 @value = __value.include?('.') ? __value.to_f : __value.to_i @unit = (__unit == 'px' || @value == 0) ? nil : __unit else raise TypeError, "#{length.class} can't be coerced into Length" end end |
Class Method Details
.default_format ⇒ String
Returns a format that is used when called #to_s without an argument.
471 472 473 |
# File 'lib/dyi/length.rb', line 471 def default_format @@default_format end |
.default_format=(fromat) ⇒ Object
Sets a format string that is used when called #to_s. The format string that is set at this method is used permanently. Use set_default_format with a block when you want to use a format string temporarily.
The format string is same as Numeric#strfnum format. In addition to place-holder of Numeric#strfnum, following placeholder can be used.
"u"
(unit placeholder)-
Placeholder ‘
u
’ is replaced as a unit. If the unit is user unit, ‘u
’ is repleced as ‘px’. "U"
(unit placeholder)-
Placeholder ‘
U
’ is replaced as a unit. If the unit is user unit, ‘U
’ is replece as empty string. "\"
(Escape Character)-
Causes the next character to be interpreted as a literal.
493 494 495 |
# File 'lib/dyi/length.rb', line 493 def default_format=(fromat) @@default_format = fromat.clone end |
.new(length) ⇒ Length .new(num) ⇒ Length .new(str) ⇒ Length
Creates and returns a new instance of Length provided the argument is not an instace of Length. If the argument is an instace of Length, returns the argument itself.
409 410 411 412 |
# File 'lib/dyi/length.rb', line 409 def new(*args) return args.first if args.size == 1 && args.first.instance_of?(self) super end |
.new_or_nil(*args) ⇒ Length?
Returns a new instace of Length if the argments is not nil
(calls Length.new
method), but returns nil
if the argument is nil
.
419 420 421 |
# File 'lib/dyi/length.rb', line 419 def new_or_nil(*args) (args.size == 1 && args.first.nil?) ? nil : new(*args) end |
.set_default_format(format) { ... } ⇒ Coordinate .set_default_format(format) ⇒ String
Invokes block with given format string as default format.
456 457 458 459 460 461 462 463 464 465 466 |
# File 'lib/dyi/length.rb', line 456 def set_default_format(format) if block_given? org_format = @@default_format self.default_format = format yield @@default_format = org_format self else self.default_format = format end end |
.unit_ratio(unit) ⇒ Float
Returns a coefficient that is used for conversion from unit into user unit.
429 430 431 432 433 434 |
# File 'lib/dyi/length.rb', line 429 def unit_ratio(unit) unless ratio = @@units[unit.to_s] raise ArgumentError, "unit `#{unit}' can not be converted into another unit" end ratio end |
Instance Method Details
#%(other) ⇒ Number Also known as: modulo
Return a number which is the modulo after division of the receiver by other.
185 186 187 188 189 190 191 192 193 194 195 196 |
# File 'lib/dyi/length.rb', line 185 def % (other) case other when Length if @unit == other.unit new_length(@value % other._num) else self.class.new(to_f % other.to_f) end else raise TypeError, "#{other.class} can't be coerced into Length" end end |
#*(number) ⇒ Length
Returns a new muliplicative length of the receiver by number.
152 153 154 |
# File 'lib/dyi/length.rb', line 152 def *(number) new_length(@value * number) end |
#**(number) ⇒ Length
Raises a length the number power.
159 160 161 |
# File 'lib/dyi/length.rb', line 159 def **(number) new_length(@value ** number) end |
#+(other) ⇒ Length
Returns a new length which is the sum of the receiver and other. First, other is converted into Length
.
125 126 127 128 129 130 131 132 |
# File 'lib/dyi/length.rb', line 125 def +(other) other = self.class.new(other) if @unit == other._unit new_length(@value + other._num) else self.class.new(to_f + other.to_f) end end |
#+@ ⇒ Length
Unary Plus – Returns the receiver’s value.
110 111 112 |
# File 'lib/dyi/length.rb', line 110 def +@ self end |
#-(other) ⇒ Length
Returns a new length which is the difference of the receiver and other. First other is converted into Length
.
140 141 142 143 144 145 146 147 |
# File 'lib/dyi/length.rb', line 140 def -(other) other = self.class.new(other) if @unit == other._unit new_length(@value - other._num) else self.class.new(to_f - other.to_f) end end |
#-@ ⇒ Length
Unary Minus – Returns the receiver’s value, negated.
116 117 118 |
# File 'lib/dyi/length.rb', line 116 def -@ new_length(-@value) end |
#/(other) ⇒ Float #/(number) ⇒ Length Also known as: quo
Divisional operator
211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
# File 'lib/dyi/length.rb', line 211 def /(number) case number when Numeric new_length(@value.quo(number.to_f)) when Length if @unit == number.unit @value.quo(number._num.to_f) else to_f.quo(number.to_f) end else raise TypeError, "#{number.class} can't be coerced into Numeric or Length" end end |
#<=>(other) ⇒ Fixnum?
Comparision – compares two values. This is the basis for the tests in Comparable
.
262 263 264 265 266 267 268 269 |
# File 'lib/dyi/length.rb', line 262 def <=>(other) return nil unless other.kind_of?(Length) if @unit == other._unit @value <=> other._num else to_f <=> other.to_f rescue nil end end |
#abs ⇒ Length
Returns the absolute length of the receiver.
253 254 255 |
# File 'lib/dyi/length.rb', line 253 def abs @value >= 0 ? self : -self end |
#clone ⇒ Object
230 231 232 |
# File 'lib/dyi/length.rb', line 230 def clone raise TypeError, "allocator undefined for Length" end |
#div(other) ⇒ Number
Returns a number which is the result of dividing the receiver by other.
167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/dyi/length.rb', line 167 def div(other) case other when Length if @unit == other.unit @value.div(other._num) else to_f.div(other.to_f) end else raise TypeError, "#{other.class} can't be coerced into Length" end end |
#dup ⇒ Object
235 236 237 |
# File 'lib/dyi/length.rb', line 235 def dup raise TypeError, "allocator undefined for Length" end |
#inspect ⇒ Object
365 366 367 |
# File 'lib/dyi/length.rb', line 365 def inspect @value.to_s + @unit.to_s end |
#nonzero? ⇒ Length?
Returns whether the receiver is a no-zero length.
247 248 249 |
# File 'lib/dyi/length.rb', line 247 def nonzero? @value == 0 ? nil : self end |
#step(limit, step) {|len| ... } ⇒ Length #step(limit, step) ⇒ Enumrator
Invokes block with the sequence of length starting at receiver.
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/dyi/length.rb', line 293 def step(limit, step) if @unit == limit._unit && @unit == step._unit self_value, limit_value, step_value = @value, limit._num, step._num else self_value, limit_value, step_value = to_f, limit.to_f, step.to_f end enum = Enumerator.new {|y| self_value.step(limit_value, step_value) do |value| self.new_length(value) end } if block_given? enum.each(&proc) self else enum end end |
#to_f(unit = nil) ⇒ Float
Returns amount part of the length converted into given unit as float. If parameter unit
is given, converts into user unit.
350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/dyi/length.rb', line 350 def to_f(unit=nil) unless self_ratio = @unit ? @@units[@unit] : 1.0 raise RuntimeError, "unit `#{@unit}' can not convert into user unit" end unless param_ratio = unit ? @@units[unit] : 1.0 if UNITS.include?(unit) raise RuntimeError, "unit `#{@unit}' can not convert into user unit" else raise ArgumentError, "unit `#{@unit}' is unknown unit" end end (@value * self_ratio.quo(param_ratio)).to_f end |
#to_s(format = nil) ⇒ Length
Returns a string to represent the receiver.
Format string can be specified for the argument. If no argument is given, default_format is used as format string. About format string, see the documentation of default_format method.
336 337 338 339 340 341 342 |
# File 'lib/dyi/length.rb', line 336 def to_s(format=nil) fmts = (format || @@default_format).split('\\\\') fmts = fmts.map do |fmt| fmt.gsub(/(?!\\U)(.|\G)U/, '\\1' + (@unit == '%' ? '\\%' : @unit.to_s)).gsub(/(?!\\u)(.|\G)u/, '\\1' + (@unit == '%' ? '\\%' : unit)) end @value.strfnum(fmts.join('\\\\')) end |
#to_user_unit ⇒ Length
Returns a length that converted into length of user unit.
314 315 316 |
# File 'lib/dyi/length.rb', line 314 def to_user_unit @unit ? self.class.new(to_f) : self end |
#unit ⇒ String
Returns the receiver’s unit. If receiver has no unit, returns ‘px’.
273 274 275 |
# File 'lib/dyi/length.rb', line 273 def unit @unit.nil? ? 'px' : @unit end |
#zero? ⇒ Boolean
Returns whether the receiver is a zero length.
241 242 243 |
# File 'lib/dyi/length.rb', line 241 def zero? @value == 0 end |