When no block given, returns a new Array new_array
of size self.size
whose elements are Arrays.
Each nested array new_array[n]
is of size other_arrays.size+1
, and contains:
The nth element of self
.
The nth element of each of the other_arrays
.
If all other_arrays
and self
are the same size:
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
If any array in other_arrays
is smaller than self
, fills to self.size
with nil
:
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2] c = [:c0, :c1] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]]
If any array in other_arrays
is larger than self
, its trailing elements are ignored:
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3, :b4] c = [:c0, :c1, :c2, :c3, :c4, :c5] d = a.zip(b, c) d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]]
When a block is given, calls the block with each of the sub-arrays (formed as above); returns nil
:
a = [:a0, :a1, :a2, :a3] b = [:b0, :b1, :b2, :b3] c = [:c0, :c1, :c2, :c3] a.zip(b, c) {|sub_array| p sub_array} # => nil
Output:
[:a0, :b0, :c0] [:a1, :b1, :c1] [:a2, :b2, :c2] [:a3, :b3, :c3]
Transposes the rows and columns in an Array of Arrays; the nested Arrays must all be the same size:
a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]] a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]]
Returns a Hash
containing implementation-dependent counters inside the VM.
This hash includes information about method/constant caches:
{ :constant_cache_invalidations=>2, :constant_cache_misses=>14, :global_cvar_state=>27 }
If USE_DEBUG_COUNTER
is enabled, debug counters will be included.
The contents of the hash are implementation specific and may be changed in the future.
This method is only expected to work on C Ruby.
Returns self
truncated (toward zero) to a precision of ndigits
decimal digits.
When ndigits
is negative, the returned value has at least ndigits.abs
trailing zeros:
555.truncate(-1) # => 550 555.truncate(-2) # => 500 -555.truncate(-2) # => -500
Returns self
when ndigits
is zero or positive.
555.truncate # => 555 555.truncate(50) # => 555
Related: Integer#round
.
Returns self
truncated (toward zero) to a precision of digits
decimal digits.
Numeric implements this by converting self
to a Float
and invoking Float#truncate
.
Generates a sequence of numbers; with a block given, traverses the sequence. Of the Core and Standard Library classes, Integer, Float, and Rational use this implementation. A quick example: squares = [] 1.step(by: 2, to: 10) {|i| squares.push(i*i) } squares # => [1, 9, 25, 49, 81] The generated sequence: - Begins with +self+. - Continues at intervals of +step+ (which may not be zero). - Ends with the last number that is within or equal to +limit+; that is, less than or equal to +limit+ if +step+ is positive, greater than or equal to +limit+ if +step+ is negative. If +limit+ is not given, the sequence is of infinite length. If a block is given, calls the block with each number in the sequence; returns +self+. If no block is given, returns an Enumerator::ArithmeticSequence. <b>Keyword Arguments</b> With keyword arguments +by+ and +to+, their values (or defaults) determine the step and limit: # Both keywords given. squares = [] 4.step(by: 2, to: 10) {|i| squares.push(i*i) } # => 4 squares # => [16, 36, 64, 100] cubes = [] 3.step(by: -1.5, to: -3) {|i| cubes.push(i*i*i) } # => 3 cubes # => [27.0, 3.375, 0.0, -3.375, -27.0] squares = [] 1.2.step(by: 0.2, to: 2.0) {|f| squares.push(f*f) } squares # => [1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] squares = [] Rational(6/5).step(by: 0.2, to: 2.0) {|r| squares.push(r*r) } squares # => [1.0, 1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] # Only keyword to given. squares = [] 4.step(to: 10) {|i| squares.push(i*i) } # => 4 squares # => [16, 25, 36, 49, 64, 81, 100] # Only by given. # Only keyword by given squares = [] 4.step(by:2) {|i| squares.push(i*i); break if i > 10 } squares # => [16, 36, 64, 100, 144] # No block given. e = 3.step(by: -1.5, to: -3) # => (3.step(by: -1.5, to: -3)) e.class # => Enumerator::ArithmeticSequence <b>Positional Arguments</b> With optional positional arguments +limit+ and +step+, their values (or defaults) determine the step and limit: squares = [] 4.step(10, 2) {|i| squares.push(i*i) } # => 4 squares # => [16, 36, 64, 100] squares = [] 4.step(10) {|i| squares.push(i*i) } squares # => [16, 25, 36, 49, 64, 81, 100] squares = [] 4.step {|i| squares.push(i*i); break if i > 10 } # => nil squares # => [16, 25, 36, 49, 64, 81, 100, 121]
Implementation Notes
If all the arguments are integers, the loop operates using an integer counter. If any of the arguments are floating point numbers, all are converted to floats, and the loop is executed <i>floor(n + n*Float::EPSILON) + 1</i> times, where <i>n = (limit - self)/step</i>.
Returns the Integer index of the last occurrence of the given substring
, or nil
if none found:
'foo'.rindex('f') # => 0 'foo'.rindex('o') # => 2 'foo'.rindex('oo') # => 1 'foo'.rindex('ooo') # => nil
Returns the Integer index of the last match for the given Regexp regexp
, or nil
if none found:
'foo'.rindex(/f/) # => 0 'foo'.rindex(/o/) # => 2 'foo'.rindex(/oo/) # => 1 'foo'.rindex(/ooo/) # => nil
The last match means starting at the possible last position, not the last of longest matches.
'foo'.rindex(/o+/) # => 2 $~ #=> #<MatchData "o">
To get the last longest match, needs to combine with negative lookbehind.
'foo'.rindex(/(?<!o)o+/) # => 1 $~ #=> #<MatchData "oo">
Or String#index
with negative lookforward.
'foo'.index(/o+(?!.*o)/) # => 1 $~ #=> #<MatchData "oo">
Integer argument offset
, if given and non-negative, specifies the maximum starting position in the
string to _end_ the search: 'foo'.rindex('o', 0) # => nil 'foo'.rindex('o', 1) # => 1 'foo'.rindex('o', 2) # => 2 'foo'.rindex('o', 3) # => 2
If offset
is a negative Integer, the maximum starting position in the string to end the search is the sum of the string’s length and offset
:
'foo'.rindex('o', -1) # => 2 'foo'.rindex('o', -2) # => 1 'foo'.rindex('o', -3) # => nil 'foo'.rindex('o', -4) # => nil
Related: String#index
.
Returns the Integer byte-based index of the last occurrence of the given substring
, or nil
if none found:
'foo'.byterindex('f') # => 0 'foo'.byterindex('o') # => 2 'foo'.byterindex('oo') # => 1 'foo'.byterindex('ooo') # => nil
Returns the Integer byte-based index of the last match for the given Regexp regexp
, or nil
if none found:
'foo'.byterindex(/f/) # => 0 'foo'.byterindex(/o/) # => 2 'foo'.byterindex(/oo/) # => 1 'foo'.byterindex(/ooo/) # => nil
The last match means starting at the possible last position, not the last of longest matches.
'foo'.byterindex(/o+/) # => 2 $~ #=> #<MatchData "o">
To get the last longest match, needs to combine with negative lookbehind.
'foo'.byterindex(/(?<!o)o+/) # => 1 $~ #=> #<MatchData "oo">
Or String#byteindex
with negative lookforward.
'foo'.byteindex(/o+(?!.*o)/) # => 1 $~ #=> #<MatchData "oo">
Integer argument offset
, if given and non-negative, specifies the maximum starting byte-based position in the
string to _end_ the search: 'foo'.byterindex('o', 0) # => nil 'foo'.byterindex('o', 1) # => 1 'foo'.byterindex('o', 2) # => 2 'foo'.byterindex('o', 3) # => 2
If offset
is a negative Integer, the maximum starting position in the string to end the search is the sum of the string’s length and offset
:
'foo'.byterindex('o', -1) # => 2 'foo'.byterindex('o', -2) # => 1 'foo'.byterindex('o', -3) # => nil 'foo'.byterindex('o', -4) # => nil
If offset
does not land on character (codepoint) boundary, IndexError
is raised.
Related: String#byteindex
.
Returns a left-justified copy of self
.
If integer argument size
is greater than the size (in characters) of self
, returns a new string of length size
that is a copy of self
, left justified and padded on the right with pad_string
:
'hello'.ljust(10) # => "hello " ' hello'.ljust(10) # => " hello " 'hello'.ljust(10, 'ab') # => "helloababa" 'тест'.ljust(10) # => "тест " 'こんにちは'.ljust(10) # => "こんにちは "
If size
is not greater than the size of self
, returns a copy of self
:
'hello'.ljust(5) # => "hello" 'hello'.ljust(1) # => "hello"
Related: String#rjust
, String#center
.
Returns a right-justified copy of self
.
If integer argument size
is greater than the size (in characters) of self
, returns a new string of length size
that is a copy of self
, right justified and padded on the left with pad_string
:
'hello'.rjust(10) # => " hello" 'hello '.rjust(10) # => " hello " 'hello'.rjust(10, 'ab') # => "ababahello" 'тест'.rjust(10) # => " тест" 'こんにちは'.rjust(10) # => " こんにちは"
If size
is not greater than the size of self
, returns a copy of self
:
'hello'.rjust(5, 'ab') # => "hello" 'hello'.rjust(1, 'ab') # => "hello"
Related: String#ljust
, String#center
.
Returns a copy of self
with each character specified by string selector
translated to the corresponding character in string replacements
. The correspondence is positional:
Each occurrence of the first character specified by selector
is translated to the first character in replacements
.
Each occurrence of the second character specified by selector
is translated to the second character in replacements
.
And so on.
Example:
'hello'.tr('el', 'ip') #=> "hippo"
If replacements
is shorter than selector
, it is implicitly padded with its own last character:
'hello'.tr('aeiou', '-') # => "h-ll-" 'hello'.tr('aeiou', 'AA-') # => "hAll-"
Arguments selector
and replacements
must be valid character selectors (see Character Selectors), and may use any of its valid forms, including negation, ranges, and escaping:
# Negation. 'hello'.tr('^aeiou', '-') # => "-e--o" # Ranges. 'ibm'.tr('b-z', 'a-z') # => "hal" # Escapes. 'hel^lo'.tr('\^aeiou', '-') # => "h-l-l-" # Escaped leading caret. 'i-b-m'.tr('b\-z', 'a-z') # => "ibabm" # Escaped embedded hyphen. 'foo\\bar'.tr('ab\\', 'XYZ') # => "fooZYXr" # Escaped backslash.
Like String#tr
, but also squeezes the modified portions of the translated string; returns a new string (translated and squeezed).
'hello'.tr_s('l', 'r') #=> "hero" 'hello'.tr_s('el', '-') #=> "h-o" 'hello'.tr_s('el', 'hx') #=> "hhxo"
Related: String#squeeze
.
Like String#tr
, but modifies self
in place. Returns self
if any changes were made, nil
otherwise.
Returns self
truncated (toward zero) to a precision of ndigits
decimal digits.
When ndigits
is positive, returns a float with ndigits
digits after the decimal point (as available):
f = 12345.6789 f.truncate(1) # => 12345.6 f.truncate(3) # => 12345.678 f = -12345.6789 f.truncate(1) # => -12345.6 f.truncate(3) # => -12345.678
When ndigits
is negative, returns an integer with at least ndigits.abs
trailing zeros:
f = 12345.6789 f.truncate(0) # => 12345 f.truncate(-3) # => 12000 f = -12345.6789 f.truncate(0) # => -12345 f.truncate(-3) # => -12000
Note that the limited precision of floating-point arithmetic may lead to surprising results:
(0.3 / 0.1).truncate #=> 2 (!)
Related: Float#round
.
Returns a copy of the storage hash for the fiber. The method can only be called on the Fiber.current
.
Sets the storage hash for the fiber. This feature is experimental and may change in the future. The method can only be called on the Fiber.current
.
You should be careful about using this method as you may inadvertently clear important fiber-storage state. You should mostly prefer to assign specific keys in the storage using Fiber::[]=
.
You can also use Fiber.new(storage: nil)
to create a fiber with an empty storage.
Example:
while request = request_queue.pop # Reset the per-request state: Fiber.current.storage = nil handle_request(request) end
Returns the current execution stack of the fiber. start
, count
and end
allow to select only parts of the backtrace.
def level3 Fiber.yield end def level2 level3 end def level1 level2 end f = Fiber.new { level1 } # It is empty before the fiber started f.backtrace #=> [] f.resume f.backtrace #=> ["test.rb:2:in `yield'", "test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'", "test.rb:13:in `block in <main>'"] p f.backtrace(1) # start from the item 1 #=> ["test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'", "test.rb:13:in `block in <main>'"] p f.backtrace(2, 2) # start from item 2, take 2 #=> ["test.rb:6:in `level2'", "test.rb:10:in `level1'"] p f.backtrace(1..3) # take items from 1 to 3 #=> ["test.rb:2:in `level3'", "test.rb:6:in `level2'", "test.rb:10:in `level1'"] f.resume # It is nil after the fiber is finished f.backtrace #=> nil
Transfer control to another fiber, resuming it from where it last stopped or starting it if it was not resumed before. The calling fiber will be suspended much like in a call to Fiber.yield
.
The fiber which receives the transfer call treats it much like a resume call. Arguments passed to transfer are treated like those passed to resume.
The two style of control passing to and from fiber (one is resume
and Fiber::yield
, another is transfer
to and from fiber) can’t be freely mixed.
If the Fiber’s lifecycle had started with transfer, it will never be able to yield or be resumed control passing, only finish or transfer back. (It still can resume other fibers that are allowed to be resumed.)
If the Fiber’s lifecycle had started with resume, it can yield or transfer to another Fiber
, but can receive control back only the way compatible with the way it was given away: if it had transferred, it only can be transferred back, and if it had yielded, it only can be resumed back. After that, it again can transfer or yield.
If those rules are broken FiberError
is raised.
For an individual Fiber
design, yield/resume is easier to use (the Fiber
just gives away control, it doesn’t need to think about who the control is given to), while transfer is more flexible for complex cases, allowing to build arbitrary graphs of Fibers dependent on each other.
Example:
manager = nil # For local var to be visible inside worker block # This fiber would be started with transfer # It can't yield, and can't be resumed worker = Fiber.new { |work| puts "Worker: starts" puts "Worker: Performed #{work.inspect}, transferring back" # Fiber.yield # this would raise FiberError: attempt to yield on a not resumed fiber # manager.resume # this would raise FiberError: attempt to resume a resumed fiber (double resume) manager.transfer(work.capitalize) } # This fiber would be started with resume # It can yield or transfer, and can be transferred # back or resumed manager = Fiber.new { puts "Manager: starts" puts "Manager: transferring 'something' to worker" result = worker.transfer('something') puts "Manager: worker returned #{result.inspect}" # worker.resume # this would raise FiberError: attempt to resume a transferring fiber Fiber.yield # this is OK, the fiber transferred from and to, now it can yield puts "Manager: finished" } puts "Starting the manager" manager.resume puts "Resuming the manager" # manager.transfer # this would raise FiberError: attempt to transfer to a yielding fiber manager.resume
produces
Starting the manager Manager: starts Manager: transferring 'something' to worker Worker: starts Worker: Performed "something", transferring back Manager: worker returned "Something" Resuming the manager Manager: finished
Returns true
if the named file is a directory, false
otherwise.
Returns a File::Stat
object for the file at filepath
(see File::Stat
):
File.stat('t.txt').class # => File::Stat
Like File::stat
, but does not follow the last symbolic link; instead, returns a File::Stat
object for the link itself.
File.symlink('t.txt', 'symlink') File.stat('symlink').size # => 47 File.lstat('symlink').size # => 5
Truncates the file file_name to be at most integer bytes long. Not available on all platforms.
f = File.new("out", "w") f.write("1234567890") #=> 10 f.close #=> nil File.truncate("out", 5) #=> 0 File.size("out") #=> 5
Like File#stat
, but does not follow the last symbolic link; instead, returns a File::Stat
object for the link itself:
File.symlink('t.txt', 'symlink') f = File.new('symlink') f.stat.size # => 47 f.lstat.size # => 11
Truncates file to at most integer bytes. The file must be opened for writing. Not available on all platforms.
f = File.new("out", "w") f.syswrite("1234567890") #=> 10 f.truncate(5) #=> 0 f.close() #=> nil File.size("out") #=> 5
Return true
if the named file exists.
file_name can be an IO
object.
“file exists” means that stat() or fstat() system call is successful.