An instance of class IO (commonly called a stream) represents an input/output stream in the underlying operating system. Class IO is the basis for input and output in Ruby.
Class File
is the only class in the Ruby core that is a subclass of IO. Some classes in the Ruby standard library are also subclasses of IO; these include TCPSocket
and UDPSocket
.
The global constant ARGF
(also accessible as $<
) provides an IO-like stream that allows access to all file paths found in ARGV (or found in STDIN if ARGV is empty). ARGF
is not itself a subclass of IO.
Class StringIO
provides an IO-like stream that handles a String
. StringIO is not itself a subclass of IO.
Important objects based on IO include:
$stdin.
$stdout.
$stderr.
Instances of class File
.
An instance of IO may be created using:
IO.new
: returns a new IO object for the given integer file descriptor.
IO.open
: passes a new IO object to the given block.
IO.popen
: returns a new IO object that is connected to the $stdin and $stdout of a newly-launched subprocess.
Kernel#open
: Returns a new IO object connected to a given source: stream, file, or subprocess.
Like a File stream, an IO stream has:
A read/write mode, which may be read-only, write-only, or read/write; see Read/Write Mode.
A data mode, which may be text-only or binary; see Data Mode.
Internal and external encodings; see Encodings.
And like other IO streams, it has:
A position, which determines where in the stream the next read or write is to occur; see Position.
A line number, which is a special, line-oriented, “position” (different from the position mentioned above); see Line Number.
io/console
Extension io/console
provides numerous methods for interacting with the console; requiring it adds numerous methods to class IO.
Many examples here use these variables:
# English text with newlines. text = <<~EOT First line Second line Fourth line Fifth line EOT # Russian text. russian = "\u{442 435 441 442}" # => "тест" # Binary data. data = "\u9990\u9991\u9992\u9993\u9994" # Text file. File.write('t.txt', text) # File with Russian text. File.write('t.rus', russian) # File with binary data. f = File.new('t.dat', 'wb:UTF-16') f.write(data) f.close
A number of IO methods accept optional keyword arguments that determine how a new stream is to be opened:
:mode
: Stream mode.
:flags
: Integer file open flags; If mode
is also given, the two are bitwise-ORed.
:external_encoding
: External encoding for the stream.
:internal_encoding
: Internal encoding for the stream. '-'
is a synonym for the default internal encoding. If the value is nil
no conversion occurs.
:encoding
: Specifies external and internal encodings as 'extern:intern'
.
:textmode
: If a truthy value, specifies the mode as text-only, binary otherwise.
:binmode
: If a truthy value, specifies the mode as binary, text-only otherwise.
:autoclose
: If a truthy value, specifies that the fd
will close when the stream closes; otherwise it remains open.
:path:
If a string value is provided, it is used in inspect
and is available as path
method.
Also available are the options offered in String#encode
, which may control conversion between external internal encoding.
You can perform basic stream IO with these methods, which typically operate on multi-byte strings:
IO#read
: Reads and returns some or all of the remaining bytes from the stream.
IO#write
: Writes zero or more strings to the stream; each given object that is not already a string is converted via to_s
.
An IO stream has a nonnegative integer position, which is the byte offset at which the next read or write is to occur. A new stream has position zero (and line number zero); method rewind
resets the position (and line number) to zero.
The relevant methods:
IO#tell
(aliased as #pos
): Returns the current position (in bytes) in the stream.
IO#pos=
: Sets the position of the stream to a given integer new_position
(in bytes).
IO#seek
: Sets the position of the stream to a given integer offset
(in bytes), relative to a given position whence
(indicating the beginning, end, or current position).
IO#rewind
: Positions the stream at the beginning (also resetting the line number).
A new IO stream may be open for reading, open for writing, or both.
A stream is automatically closed when claimed by the garbage collector.
Attempted reading or writing on a closed stream raises an exception.
The relevant methods:
IO#close
: Closes the stream for both reading and writing.
IO#close_read
: Closes the stream for reading.
IO#close_write
: Closes the stream for writing.
IO#closed?
: Returns whether the stream is closed.
You can query whether a stream is positioned at its end:
IO#eof?
(also aliased as #eof
): Returns whether the stream is at end-of-stream.
You can reposition to end-of-stream by using method IO#seek
:
f = File.new('t.txt') f.eof? # => false f.seek(0, :END) f.eof? # => true f.close
Or by reading all stream content (which is slower than using IO#seek
):
f.rewind f.eof? # => false f.read # => "First line\nSecond line\n\nFourth line\nFifth line\n" f.eof? # => true
You can read an IO stream line-by-line using these methods:
IO#each_line
: Reads each remaining line, passing it to the given block.
IO#gets
: Returns the next line.
IO#readline
: Like gets
, but raises an exception at end-of-stream.
IO#readlines
: Returns all remaining lines in an array.
Each of these reader methods accepts:
An optional line separator, sep
; see Line Separator.
An optional line-size limit, limit
; see Line Limit.
For each of these reader methods, reading may begin mid-line, depending on the stream’s position; see Position:
f = File.new('t.txt') f.pos = 27 f.each_line {|line| p line } f.close
Output:
"rth line\n" "Fifth line\n"
You can write to an IO stream line-by-line using this method:
IO#puts
: Writes objects to the stream.
Each of these methods uses a line separator, which is the string that delimits lines:
The default line separator is the given by the global variable $/
, whose value is by default "\n"
. The line to be read next is all data from the current position to the next line separator:
f = File.new('t.txt') f.gets # => "First line\n" f.gets # => "Second line\n" f.gets # => "\n" f.gets # => "Fourth line\n" f.gets # => "Fifth line\n" f.close
You can specify a different line separator:
f = File.new('t.txt') f.gets('l') # => "First l" f.gets('li') # => "ine\nSecond li" f.gets('lin') # => "ne\n\nFourth lin" f.gets # => "e\n" f.close
There are two special line separators:
nil
: The entire stream is read into a single string:
f = File.new('t.txt') f.gets(nil) # => "First line\nSecond line\n\nFourth line\nFifth line\n" f.close
''
(the empty string): The next “paragraph” is read (paragraphs being separated by two consecutive line separators):
f = File.new('t.txt') f.gets('') # => "First line\nSecond line\n\n" f.gets('') # => "Fourth line\nFifth line\n" f.close
Each of these methods uses a line limit, which specifies that the number of bytes returned may not be (much) longer than the given limit
;
A multi-byte character will not be split, and so a line may be slightly longer than the given limit.
If limit
is not given, the line is determined only by sep
.
# Text with 1-byte characters. File.open('t.txt') {|f| f.gets(1) } # => "F" File.open('t.txt') {|f| f.gets(2) } # => "Fi" File.open('t.txt') {|f| f.gets(3) } # => "Fir" File.open('t.txt') {|f| f.gets(4) } # => "Firs" # No more than one line. File.open('t.txt') {|f| f.gets(10) } # => "First line" File.open('t.txt') {|f| f.gets(11) } # => "First line\n" File.open('t.txt') {|f| f.gets(12) } # => "First line\n" # Text with 2-byte characters, which will not be split. File.open('t.rus') {|f| f.gets(1).size } # => 1 File.open('t.rus') {|f| f.gets(2).size } # => 1 File.open('t.rus') {|f| f.gets(3).size } # => 2 File.open('t.rus') {|f| f.gets(4).size } # => 2
With arguments sep
and limit
given, combines the two behaviors:
Returns the next line as determined by line separator sep
.
But returns no more bytes than are allowed by the limit.
Example:
File.open('t.txt') {|f| f.gets('li', 20) } # => "First li" File.open('t.txt') {|f| f.gets('li', 2) } # => "Fi"
A readable IO stream has a non-negative integer line number.
The relevant methods:
IO#lineno
: Returns the line number.
IO#lineno=
: Resets and returns the line number.
Unless modified by a call to method IO#lineno=
, the line number is the number of lines read by certain line-oriented methods, according to the given line separator sep
:
IO.foreach
: Increments the line number on each call to the block.
IO#each_line
: Increments the line number on each call to the block.
IO#gets
: Increments the line number.
IO#readline
: Increments the line number.
IO#readlines
: Increments the line number for each line read.
A new stream is initially has line number zero (and position zero); method rewind
resets the line number (and position) to zero:
f = File.new('t.txt') f.lineno # => 0 f.gets # => "First line\n" f.lineno # => 1 f.rewind f.lineno # => 0 f.close
Reading lines from a stream usually changes its line number:
f = File.new('t.txt', 'r') f.lineno # => 0 f.readline # => "This is line one.\n" f.lineno # => 1 f.readline # => "This is the second line.\n" f.lineno # => 2 f.readline # => "Here's the third line.\n" f.lineno # => 3 f.eof? # => true f.close
Iterating over lines in a stream usually changes its line number:
File.open('t.txt') do |f| f.each_line do |line| p "position=#{f.pos} eof?=#{f.eof?} lineno=#{f.lineno}" end end
Output:
"position=11 eof?=false lineno=1" "position=23 eof?=false lineno=2" "position=24 eof?=false lineno=3" "position=36 eof?=false lineno=4" "position=47 eof?=true lineno=5"
Unlike the stream’s position, the line number does not affect where the next read or write will occur:
f = File.new('t.txt') f.lineno = 1000 f.lineno # => 1000 f.gets # => "First line\n" f.lineno # => 1001 f.close
Associated with the line number is the global variable $.
:
When a stream is opened, $.
is not set; its value is left over from previous activity in the process:
$. = 41 f = File.new('t.txt') $. = 41 # => 41 f.close
When a stream is read, #.
is set to the line number for that stream:
f0 = File.new('t.txt') f1 = File.new('t.dat') f0.readlines # => ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"] $. # => 5 f1.readlines # => ["\xFE\xFF\x99\x90\x99\x91\x99\x92\x99\x93\x99\x94"] $. # => 1 f0.close f1.close
Methods IO#rewind
and IO#seek
do not affect $.
:
f = File.new('t.txt') f.readlines # => ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"] $. # => 5 f.rewind f.seek(0, :SET) $. # => 5 f.close
You can process an IO stream character-by-character using these methods:
IO#getc
: Reads and returns the next character from the stream.
IO#readchar
: Like getc
, but raises an exception at end-of-stream.
IO#ungetc
: Pushes back (“unshifts”) a character or integer onto the stream.
IO#putc
: Writes a character to the stream.
IO#each_char
: Reads each remaining character in the stream, passing the character to the given block.
You can process an IO stream byte-by-byte using these methods:
IO#getbyte
: Returns the next 8-bit byte as an integer in range 0..255.
IO#readbyte
: Like getbyte
, but raises an exception if at end-of-stream.
IO#ungetbyte
: Pushes back (“unshifts”) a byte back onto the stream.
IO#each_byte
: Reads each remaining byte in the stream, passing the byte to the given block.
You can process an IO stream codepoint-by-codepoint:
IO#each_codepoint
: Reads each remaining codepoint, passing it to the given block.
First, what’s elsewhere. Class IO:
Inherits from class Object.
Includes module Enumerable, which provides dozens of additional methods.
Here, class IO provides methods that are useful for:
::new
(aliased as ::for_fd
): Creates and returns a new IO object for the given integer file descriptor.
::open
: Creates a new IO object.
::pipe
: Creates a connected pair of reader and writer IO objects.
::popen
: Creates an IO object to interact with a subprocess.
::select
: Selects which given IO instances are ready for reading, writing, or have pending exceptions.
::binread
: Returns a binary string with all or a subset of bytes from the given file.
::read
: Returns a string with all or a subset of bytes from the given file.
::readlines
: Returns an array of strings, which are the lines from the given file.
getbyte
: Returns the next 8-bit byte read from self
as an integer.
getc
: Returns the next character read from self
as a string.
gets
: Returns the line read from self
.
pread
: Returns all or the next n bytes read from self
, not updating the receiver’s offset.
read
: Returns all remaining or the next n bytes read from self
for a given n.
read_nonblock
: the next n bytes read from self
for a given n, in non-block mode.
readbyte
: Returns the next byte read from self
; same as getbyte
, but raises an exception on end-of-stream.
readchar
: Returns the next character read from self
; same as getc
, but raises an exception on end-of-stream.
readline
: Returns the next line read from self
; same as getline, but raises an exception of end-of-stream.
readlines
: Returns an array of all lines read read from self
.
readpartial
: Returns up to the given number of bytes from self
.
::binwrite
: Writes the given string to the file at the given filepath, in binary mode.
::write
: Writes the given string to self
.
<<
: Appends the given string to self
.
print
: Prints last read line or given objects to self
.
printf
: Writes to self
based on the given format string and objects.
putc
: Writes a character to self
.
puts
: Writes lines to self
, making sure line ends with a newline.
pwrite
: Writes the given string at the given offset, not updating the receiver’s offset.
write
: Writes one or more given strings to self
.
write_nonblock
: Writes one or more given strings to self
in non-blocking mode.
lineno
: Returns the current line number in self
.
lineno=
: Sets the line number is self
.
pos
(aliased as tell
): Returns the current byte offset in self
.
pos=
: Sets the byte offset in self
.
reopen
: Reassociates self
with a new or existing IO stream.
rewind
: Positions self
to the beginning of input.
seek
: Sets the offset for self
relative to given position.
::foreach
: Yields each line of given file to the block.
each
(aliased as each_line
): Calls the given block with each successive line in self
.
each_byte
: Calls the given block with each successive byte in self
as an integer.
each_char
: Calls the given block with each successive character in self
as a string.
each_codepoint
: Calls the given block with each successive codepoint in self
as an integer.
autoclose=
: Sets whether self
auto-closes.
binmode
: Sets self
to binary mode.
close
: Closes self
.
close_on_exec=
: Sets the close-on-exec flag.
close_read
: Closes self
for reading.
close_write
: Closes self
for writing.
set_encoding
: Sets the encoding for self
.
set_encoding_by_bom
: Sets the encoding for self
, based on its Unicode byte-order-mark.
sync=
: Sets the sync-mode to the given value.
autoclose?
: Returns whether self
auto-closes.
binmode?
: Returns whether self
is in binary mode.
close_on_exec?
: Returns the close-on-exec flag for self
.
closed?
: Returns whether self
is closed.
eof?
(aliased as eof
): Returns whether self
is at end-of-stream.
external_encoding
: Returns the external encoding object for self
.
fileno
(aliased as to_i
): Returns the integer file descriptor for self
internal_encoding
: Returns the internal encoding object for self
.
pid
: Returns the process ID of a child process associated with self
, if self
was created by ::popen
.
stat
: Returns the File::Stat
object containing status information for self
.
sync
: Returns whether self
is in sync-mode.
tty?
(aliased as isatty
): Returns whether self
is a terminal.
fdatasync
: Immediately writes all buffered data in self
to disk.
flush
: Flushes any buffered data within self
to the underlying operating system.
fsync
: Immediately writes all buffered data and attributes in self
to disk.
ungetbyte
: Prepends buffer for self
with given integer byte or string.
ungetc
: Prepends buffer for self
with given string.
::sysopen
: Opens the file given by its path, returning the integer file descriptor.
advise
: Announces the intention to access data from self
in a specific way.
fcntl
: Passes a low-level command to the file specified by the given file descriptor.
ioctl
: Passes a low-level command to the device specified by the given file descriptor.
sysread
: Returns up to the next n bytes read from self using a low-level read.
sysseek
: Sets the offset for self
.
syswrite
: Writes the given string to self
using a low-level write.
::copy_stream
: Copies data from a source to a destination, each of which is a filepath or an IO-like object.
::try_convert
: Returns a new IO object resulting from converting the given object.
inspect
: Returns the string representation of self
.
An OpenStruct
is a data structure, similar to a Hash
, that allows the definition of arbitrary attributes with their accompanying values. This is accomplished by using Ruby’s metaprogramming to define methods on the class itself.
require "ostruct" person = OpenStruct.new person.name = "John Smith" person.age = 70 person.name # => "John Smith" person.age # => 70 person.address # => nil
An OpenStruct
employs a Hash
internally to store the attributes and values and can even be initialized with one:
australia = OpenStruct.new(:country => "Australia", :capital => "Canberra") # => #<OpenStruct country="Australia", capital="Canberra">
Hash
keys with spaces or characters that could normally not be used for method calls (e.g. ()[]*
) will not be immediately available on the OpenStruct
object as a method for retrieval or assignment, but can still be reached through the Object#send
method or using [].
measurements = OpenStruct.new("length (in inches)" => 24) measurements[:"length (in inches)"] # => 24 measurements.send("length (in inches)") # => 24 message = OpenStruct.new(:queued? => true) message.queued? # => true message.send("queued?=", false) message.queued? # => false
Removing the presence of an attribute requires the execution of the delete_field
method as setting the property value to nil
will not remove the attribute.
first_pet = OpenStruct.new(:name => "Rowdy", :owner => "John Smith") second_pet = OpenStruct.new(:name => "Rowdy") first_pet.owner = nil first_pet # => #<OpenStruct name="Rowdy", owner=nil> first_pet == second_pet # => false first_pet.delete_field(:owner) first_pet # => #<OpenStruct name="Rowdy"> first_pet == second_pet # => true
Ractor
compatibility: A frozen OpenStruct
with shareable values is itself shareable.
An OpenStruct
utilizes Ruby’s method lookup structure to find and define the necessary methods for properties. This is accomplished through the methods method_missing and define_singleton_method.
This should be a consideration if there is a concern about the performance of the objects that are created, as there is much more overhead in the setting of these properties compared to using a Hash
or a Struct
. Creating an open struct from a small Hash
and accessing a few of the entries can be 200 times slower than accessing the hash directly.
This is a potential security issue; building OpenStruct
from untrusted user data (e.g. JSON
web request) may be susceptible to a “symbol denial of service” attack since the keys create methods and names of methods are never garbage collected.
This may also be the source of incompatibilities between Ruby versions:
o = OpenStruct.new o.then # => nil in Ruby < 2.6, enumerator for Ruby >= 2.6
Builtin methods may be overwritten this way, which may be a source of bugs or security issues:
o = OpenStruct.new o.methods # => [:to_h, :marshal_load, :marshal_dump, :each_pair, ... o.methods = [:foo, :bar] o.methods # => [:foo, :bar]
To help remedy clashes, OpenStruct
uses only protected/private methods ending with !
and defines aliases for builtin public methods by adding a !
:
o = OpenStruct.new(make: 'Bentley', class: :luxury) o.class # => :luxury o.class! # => OpenStruct
It is recommended (but not enforced) to not use fields ending in !
; Note that a subclass’ methods may not be overwritten, nor can OpenStruct’s own methods ending with !
.
For all these reasons, consider not using OpenStruct
at all.
This library provides the Set
class, which deals with a collection of unordered values with no duplicates. It is a hybrid of Array’s intuitive inter-operation facilities and Hash’s fast lookup.
The method to_set
is added to Enumerable
for convenience.
Set
implements a collection of unordered values with no duplicates. This is a hybrid of Array’s intuitive inter-operation facilities and Hash’s fast lookup.
Set
is easy to use with Enumerable
objects (implementing each
). Most of the initializer methods and binary operators accept generic Enumerable
objects besides sets and arrays. An Enumerable
object can be converted to Set
using the to_set
method.
Set
uses Hash
as storage, so you must note the following points:
Equality of elements is determined according to Object#eql?
and Object#hash
. Use Set#compare_by_identity
to make a set compare its elements by their identity.
Set
assumes that the identity of each element does not change while it is stored. Modifying an element of a set will render the set to an unreliable state.
When a string is to be stored, a frozen copy of the string is stored instead unless the original string is already frozen.
The comparison operators <
, >
, <=
, and >=
are implemented as shorthand for the {proper_,}{subset?,superset?} methods. The <=>
operator reflects this order, or return nil
for sets that both have distinct elements ({x, y}
vs. {x, z}
for example).
require 'set' s1 = Set[1, 2] #=> #<Set: {1, 2}> s2 = [1, 2].to_set #=> #<Set: {1, 2}> s1 == s2 #=> true s1.add("foo") #=> #<Set: {1, 2, "foo"}> s1.merge([2, 6]) #=> #<Set: {1, 2, "foo", 6}> s1.subset?(s2) #=> false s2.subset?(s1) #=> true
Akinori MUSHA <knu@iDaemons.org> (current maintainer)
First, what’s elsewhere. Class Set:
Inherits from class Object.
Includes module Enumerable, which provides dozens of additional methods.
In particular, class Set does not have many methods of its own for fetching or for iterating. Instead, it relies on those in Enumerable.
Here, class Set provides methods that are useful for:
::[]
: Returns a new set containing the given objects.
::new
: Returns a new set containing either the given objects (if no block given) or the return values from the called block (if a block given).
| (aliased as union
and +
): Returns a new set containing all elements from self
and all elements from a given enumerable (no duplicates).
& (aliased as intersection
): Returns a new set containing all elements common to self
and a given enumerable.
- (aliased as difference
): Returns a copy of self
with all elements in a given enumerable removed.
^: Returns a new set containing all elements from self
and a given enumerable except those common to both.
<=>: Returns -1, 0, or 1 as self
is less than, equal to, or greater than a given object.
==: Returns whether self
and a given enumerable are equal, as determined by Object#eql?
.
compare_by_identity?
: Returns whether the set considers only identity when comparing elements.
empty?
: Returns whether the set has no elements.
include?
(aliased as member?
and ===
): Returns whether a given object is an element in the set.
subset?
(aliased as <=): Returns whether a given object is a subset of the set.
proper_subset?
(aliased as <): Returns whether a given enumerable is a proper subset of the set.
superset?
(aliased as >=]): Returns whether a given enumerable is a superset of the set.
proper_superset?
(aliased as >): Returns whether a given enumerable is a proper superset of the set.
disjoint?
: Returns true
if the set and a given enumerable have no common elements, false
otherwise.
intersect?
: Returns true
if the set and a given enumerable: have any common elements, false
otherwise.
compare_by_identity?
: Returns whether the set considers only identity when comparing elements.
add
(aliased as <<
): Adds a given object to the set; returns self
.
add?
: If the given object is not an element in the set, adds it and returns self
; otherwise, returns nil
.
merge
: Adds each given object to the set; returns self
.
replace
: Replaces the contents of the set with the contents of a given enumerable.
clear
: Removes all elements in the set; returns self
.
delete
: Removes a given object from the set; returns self
.
delete?
: If the given object is an element in the set, removes it and returns self
; otherwise, returns nil
.
subtract
: Removes each given object from the set; returns self
.
delete_if
- Removes elements specified by a given block.
select!
(aliased as filter!
): Removes elements not specified by a given block.
keep_if
: Removes elements not specified by a given block.
reject!
Removes elements specified by a given block.
classify
: Returns a hash that classifies the elements, as determined by the given block.
collect!
(aliased as map!
): Replaces each element with a block return-value.
divide
: Returns a hash that classifies the elements, as determined by the given block; differs from classify
in that the block may accept either one or two arguments.
flatten
: Returns a new set that is a recursive flattening of self
. flatten!
: Replaces each nested set in self
with the elements from that set.
inspect
(aliased as to_s
): Returns a string displaying the elements.
join
: Returns a string containing all elements, converted to strings as needed, and joined by the given record separator.
to_a
: Returns an array containing all set elements.
to_set
: Returns self
if given no arguments and no block; with a block given, returns a new set consisting of block return values.
each
: Calls the block with each successive element; returns self
.
reset
: Resets the internal state; useful if an object has been modified while an element in the set.
Use the Monitor
class when you want to have a lock object for blocks with mutual exclusion.
require 'monitor' lock = Monitor.new lock.synchronize do # exclusive access end
Pathname
represents the name of a file or directory on the filesystem, but not the file itself.
The pathname depends on the Operating System: Unix, Windows, etc. This library works with pathnames of local OS, however non-Unix pathnames are supported experimentally.
A Pathname
can be relative or absolute. It’s not until you try to reference the file that it even matters whether the file exists or not.
Pathname
is immutable. It has no method for destructive update.
The goal of this class is to manipulate file path information in a neater way than standard Ruby provides. The examples below demonstrate the difference.
All functionality from File
, FileTest
, and some from Dir
and FileUtils
is included, in an unsurprising way. It is essentially a facade for all of these, and more.
Pathname
require 'pathname' pn = Pathname.new("/usr/bin/ruby") size = pn.size # 27662 isdir = pn.directory? # false dir = pn.dirname # Pathname:/usr/bin base = pn.basename # Pathname:ruby dir, base = pn.split # [Pathname:/usr/bin, Pathname:ruby] data = pn.read pn.open { |f| _ } pn.each_line { |line| _ }
pn = "/usr/bin/ruby" size = File.size(pn) # 27662 isdir = File.directory?(pn) # false dir = File.dirname(pn) # "/usr/bin" base = File.basename(pn) # "ruby" dir, base = File.split(pn) # ["/usr/bin", "ruby"] data = File.read(pn) File.open(pn) { |f| _ } File.foreach(pn) { |line| _ }
p1 = Pathname.new("/usr/lib") # Pathname:/usr/lib p2 = p1 + "ruby/1.8" # Pathname:/usr/lib/ruby/1.8 p3 = p1.parent # Pathname:/usr p4 = p2.relative_path_from(p3) # Pathname:lib/ruby/1.8 pwd = Pathname.pwd # Pathname:/home/gavin pwd.absolute? # true p5 = Pathname.new "." # Pathname:. p5 = p5 + "music/../articles" # Pathname:music/../articles p5.cleanpath # Pathname:articles p5.realpath # Pathname:/home/gavin/articles p5.children # [Pathname:/home/gavin/articles/linux, ...]
These methods are effectively manipulating a String
, because that’s all a path is. None of these access the file system except for mountpoint?
, children
, each_child
, realdirpath
and realpath
.
+
File
status predicate methods These methods are a facade for FileTest:
File
property and manipulation methods These methods are a facade for File:
open
(*args, &block)
These methods are a facade for Dir:
each_entry
(&block)
IO
These methods are a facade for IO:
each_line
(*args, &block)
These methods are a mixture of Find
, FileUtils
, and others:
Method
documentation As the above section shows, most of the methods in Pathname
are facades. The documentation for these methods generally just says, for instance, “See FileTest.writable?
”, as you should be familiar with the original method anyway, and its documentation (e.g. through ri
) will contain more information. In some cases, a brief description will follow.
Ripper
is a Ruby script parser.
You can get information from the parser with event-based style. Information such as abstract syntax trees or simple lexical analysis of the Ruby program.
Ripper
provides an easy interface for parsing your program into a symbolic expression tree (or S-expression).
Understanding the output of the parser may come as a challenge, it’s recommended you use PP
to format the output for legibility.
require 'ripper' require 'pp' pp Ripper.sexp('def hello(world) "Hello, #{world}!"; end') #=> [:program, [[:def, [:@ident, "hello", [1, 4]], [:paren, [:params, [[:@ident, "world", [1, 10]]], nil, nil, nil, nil, nil, nil]], [:bodystmt, [[:string_literal, [:string_content, [:@tstring_content, "Hello, ", [1, 18]], [:string_embexpr, [[:var_ref, [:@ident, "world", [1, 27]]]]], [:@tstring_content, "!", [1, 33]]]]], nil, nil, nil]]]]
You can see in the example above, the expression starts with :program
.
From here, a method definition at :def
, followed by the method’s identifier :@ident
. After the method’s identifier comes the parentheses :paren
and the method parameters under :params
.
Next is the method body, starting at :bodystmt
(stmt
meaning statement), which contains the full definition of the method.
In our case, we’re simply returning a String
, so next we have the :string_literal
expression.
Within our :string_literal
you’ll notice two @tstring_content
, this is the literal part for Hello,
and !
. Between the two @tstring_content
statements is a :string_embexpr
, where embexpr is an embedded expression. Our expression consists of a local variable, or var_ref
, with the identifier (@ident
) of world
.
ruby 1.9 (support CVS HEAD only)
bison 1.28 or later (Other yaccs do not work)
Ruby License.
Minero Aoki
aamine@loveruby.net
SocketError
is the error class for socket.
IO streams for strings, with access similar to IO
; see IO
.
Examples on this page assume that StringIO has been required:
require 'stringio'
StringScanner
provides for lexical scanning operations on a String
. Here is an example of its usage:
require 'strscan' s = StringScanner.new('This is an example string') s.eos? # -> false p s.scan(/\w+/) # -> "This" p s.scan(/\w+/) # -> nil p s.scan(/\s+/) # -> " " p s.scan(/\s+/) # -> nil p s.scan(/\w+/) # -> "is" s.eos? # -> false p s.scan(/\s+/) # -> " " p s.scan(/\w+/) # -> "an" p s.scan(/\s+/) # -> " " p s.scan(/\w+/) # -> "example" p s.scan(/\s+/) # -> " " p s.scan(/\w+/) # -> "string" s.eos? # -> true p s.scan(/\s+/) # -> nil p s.scan(/\w+/) # -> nil
Scanning a string means remembering the position of a scan pointer, which is just an index. The point of scanning is to move forward a bit at a time, so matches are sought after the scan pointer; usually immediately after it.
Given the string “test string”, here are the pertinent scan pointer positions:
t e s t s t r i n g 0 1 2 ... 1 0
When you scan
for a pattern (a regular expression), the match must occur at the character after the scan pointer. If you use scan_until
, then the match can occur anywhere after the scan pointer. In both cases, the scan pointer moves just beyond the last character of the match, ready to scan again from the next character onwards. This is demonstrated by the example above.
Method
Categories There are other methods besides the plain scanners. You can look ahead in the string without actually scanning. You can access the most recent match. You can modify the string being scanned, reset or terminate the scanner, find out or change the position of the scan pointer, skip ahead, and so on.
beginning_of_line?
(#bol?
)
Data
There are aliases to several of the methods.
Raised by some IO
operations when reaching the end of file. Many IO
methods exist in two forms,
one that returns nil
when the end of file is reached, the other raises EOFError
.
EOFError
is a subclass of IOError
.
file = File.open("/etc/hosts") file.read file.gets #=> nil file.readline #=> EOFError: end of file reached file.close
ARGF
is a stream designed for use in scripts that process files given as command-line arguments or passed in via STDIN.
The arguments passed to your script are stored in the ARGV
Array
, one argument per element. ARGF
assumes that any arguments that aren’t filenames have been removed from ARGV
. For example:
$ ruby argf.rb --verbose file1 file2 ARGV #=> ["--verbose", "file1", "file2"] option = ARGV.shift #=> "--verbose" ARGV #=> ["file1", "file2"]
You can now use ARGF
to work with a concatenation of each of these named files. For instance, ARGF.read
will return the contents of file1 followed by the contents of file2.
After a file in ARGV
has been read ARGF
removes it from the Array
. Thus, after all files have been read ARGV
will be empty.
You can manipulate ARGV
yourself to control what ARGF
operates on. If you remove a file from ARGV
, it is ignored by ARGF
; if you add files to ARGV
, they are treated as if they were named on the command line. For example:
ARGV.replace ["file1"] ARGF.readlines # Returns the contents of file1 as an Array ARGV #=> [] ARGV.replace ["file2", "file3"] ARGF.read # Returns the contents of file2 and file3
If ARGV
is empty, ARGF
acts as if it contained STDIN, i.e. the data piped to your script. For example:
$ echo "glark" | ruby -e 'p ARGF.read' "glark\n"
ERB
– Ruby Templating ERB
provides an easy to use but powerful templating system for Ruby. Using ERB
, actual Ruby code can be added to any plain text document for the purposes of generating document information details and/or flow control.
A very simple example is this:
require 'erb' x = 42 template = ERB.new <<-EOF The value of x is: <%= x %> EOF puts template.result(binding)
Prints: The value of x is: 42
More complex examples are given below.
ERB
recognizes certain tags in the provided template and converts them based on the rules below:
<% Ruby code -- inline with output %> <%= Ruby expression -- replace with result %> <%# comment -- ignored -- useful in testing %> (`<% #` doesn't work. Don't use Ruby comments.) % a line of Ruby code -- treated as <% line %> (optional -- see ERB.new) %% replaced with % if first thing on a line and % processing is used <%% or %%> -- replace with <% or %> respectively
All other text is passed through ERB
filtering unchanged.
There are several settings you can change when you use ERB:
the nature of the tags that are recognized;
the binding used to resolve local variables in the template.
See the ERB.new
and ERB#result
methods for more detail.
ERB
(or Ruby code generated by ERB
) returns a string in the same character encoding as the input string. When the input string has a magic comment, however, it returns a string in the encoding specified by the magic comment.
# -*- coding: utf-8 -*- require 'erb' template = ERB.new <<EOF <%#-*- coding: Big5 -*-%> \_\_ENCODING\_\_ is <%= \_\_ENCODING\_\_ %>. EOF puts template.result
Prints: _ENCODING_ is Big5.
ERB
is useful for any generic templating situation. Note that in this example, we use the convenient “% at start of line” tag, and we quote the template literally with %q{...}
to avoid trouble with the backslash.
require "erb" # Create template. template = %q{ From: James Edward Gray II <james@grayproductions.net> To: <%= to %> Subject: Addressing Needs <%= to[/\w+/] %>: Just wanted to send a quick note assuring that your needs are being addressed. I want you to know that my team will keep working on the issues, especially: <%# ignore numerous minor requests -- focus on priorities %> % priorities.each do |priority| * <%= priority %> % end Thanks for your patience. James Edward Gray II }.gsub(/^ /, '') message = ERB.new(template, trim_mode: "%<>") # Set up template data. to = "Community Spokesman <spokesman@ruby_community.org>" priorities = [ "Run Ruby Quiz", "Document Modules", "Answer Questions on Ruby Talk" ] # Produce result. email = message.result puts email
Generates:
From: James Edward Gray II <james@grayproductions.net> To: Community Spokesman <spokesman@ruby_community.org> Subject: Addressing Needs Community: Just wanted to send a quick note assuring that your needs are being addressed. I want you to know that my team will keep working on the issues, especially: * Run Ruby Quiz * Document Modules * Answer Questions on Ruby Talk Thanks for your patience. James Edward Gray II
ERB
is often used in .rhtml
files (HTML with embedded Ruby). Notice the need in this example to provide a special binding when the template is run, so that the instance variables in the Product object can be resolved.
require "erb" # Build template data class. class Product def initialize( code, name, desc, cost ) @code = code @name = name @desc = desc @cost = cost @features = [ ] end def add_feature( feature ) @features << feature end # Support templating of member data. def get_binding binding end # ... end # Create template. template = %{ <html> <head><title>Ruby Toys -- <%= @name %></title></head> <body> <h1><%= @name %> (<%= @code %>)</h1> <p><%= @desc %></p> <ul> <% @features.each do |f| %> <li><b><%= f %></b></li> <% end %> </ul> <p> <% if @cost < 10 %> <b>Only <%= @cost %>!!!</b> <% else %> Call for a price, today! <% end %> </p> </body> </html> }.gsub(/^ /, '') rhtml = ERB.new(template) # Set up template data. toy = Product.new( "TZ-1002", "Rubysapien", "Geek's Best Friend! Responds to Ruby commands...", 999.95 ) toy.add_feature("Listens for verbal commands in the Ruby language!") toy.add_feature("Ignores Perl, Java, and all C variants.") toy.add_feature("Karate-Chop Action!!!") toy.add_feature("Matz signature on left leg.") toy.add_feature("Gem studded eyes... Rubies, of course!") # Produce result. rhtml.run(toy.get_binding)
Generates (some blank lines removed):
<html> <head><title>Ruby Toys -- Rubysapien</title></head> <body> <h1>Rubysapien (TZ-1002)</h1> <p>Geek's Best Friend! Responds to Ruby commands...</p> <ul> <li><b>Listens for verbal commands in the Ruby language!</b></li> <li><b>Ignores Perl, Java, and all C variants.</b></li> <li><b>Karate-Chop Action!!!</b></li> <li><b>Matz signature on left leg.</b></li> <li><b>Gem studded eyes... Rubies, of course!</b></li> </ul> <p> Call for a price, today! </p> </body> </html>
There are a variety of templating solutions available in various Ruby projects. For example, RDoc
, distributed with Ruby, uses its own template engine, which can be reused elsewhere.
Other popular engines could be found in the corresponding Category of The Ruby Toolbox.
IPAddr
provides a set of methods to manipulate an IP address. Both IPv4 and IPv6 are supported.
require 'ipaddr' ipaddr1 = IPAddr.new "3ffe:505:2::1" p ipaddr1 #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0001/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff> p ipaddr1.to_s #=> "3ffe:505:2::1" ipaddr2 = ipaddr1.mask(48) #=> #<IPAddr: IPv6:3ffe:0505:0002:0000:0000:0000:0000:0000/ffff:ffff:ffff:0000:0000:0000:0000:0000> p ipaddr2.to_s #=> "3ffe:505:2::" ipaddr3 = IPAddr.new "192.168.2.0/24" p ipaddr3 #=> #<IPAddr: IPv4:192.168.2.0/255.255.255.0>
Class Logger provides a simple but sophisticated logging utility that you can use to create one or more event logs for your program. Each such log contains a chronological sequence of entries that provides a record of the program’s activities.
All examples on this page assume that Logger has been required:
require 'logger'
Create a log with Logger.new
:
# Single log file. logger = Logger.new('t.log') # Size-based rotated logging: 3 10-megabyte files. logger = Logger.new('t.log', 3, 10485760) # Period-based rotated logging: daily (also allowed: 'weekly', 'monthly'). logger = Logger.new('t.log', 'daily') # Log to an IO stream. logger = Logger.new($stdout)
Add entries (level, message) with Logger#add
:
logger.add(Logger::DEBUG, 'Maximal debugging info') logger.add(Logger::INFO, 'Non-error information') logger.add(Logger::WARN, 'Non-error warning') logger.add(Logger::ERROR, 'Non-fatal error') logger.add(Logger::FATAL, 'Fatal error') logger.add(Logger::UNKNOWN, 'Most severe')
Close the log with Logger#close
:
logger.close
You can add entries with method Logger#add
:
logger.add(Logger::DEBUG, 'Maximal debugging info') logger.add(Logger::INFO, 'Non-error information') logger.add(Logger::WARN, 'Non-error warning') logger.add(Logger::ERROR, 'Non-fatal error') logger.add(Logger::FATAL, 'Fatal error') logger.add(Logger::UNKNOWN, 'Most severe')
These shorthand methods also add entries:
logger.debug('Maximal debugging info') logger.info('Non-error information') logger.warn('Non-error warning') logger.error('Non-fatal error') logger.fatal('Fatal error') logger.unknown('Most severe')
When you call any of these methods, the entry may or may not be written to the log, depending on the entry’s severity and on the log level; see Log Level
An entry always has:
A severity (the required argument to add
).
An automatically created timestamp.
And may also have:
A message.
A program name.
Example:
logger = Logger.new($stdout) logger.add(Logger::INFO, 'My message.', 'mung') # => I, [2022-05-07T17:21:46.536234 #20536] INFO -- mung: My message.
The default format for an entry is:
"%s, [%s #%d] %5s -- %s: %s\n"
where the values to be formatted are:
Severity (one letter).
Timestamp.
Process
id.
Severity (word).
Program name.
Message.
You can use a different entry format by:
Setting a custom format proc (affects following entries); see formatter=.
Calling any of the methods above with a block (affects only the one entry). Doing so can have two benefits:
Context: the block can evaluate the entire program context and create a context-dependent message.
Performance: the block is not evaluated unless the log level permits the entry actually to be written:
logger.error { my_slow_message_generator }
Contrast this with the string form, where the string is always evaluated, regardless of the log level:
logger.error("#{my_slow_message_generator}")
The severity of a log entry has two effects:
Determines whether the entry is selected for inclusion in the log; see Log Level.
Indicates to any log reader (whether a person or a program) the relative importance of the entry.
The timestamp for a log entry is generated automatically when the entry is created.
The logged timestamp is formatted by method Time#strftime
using this format string:
'%Y-%m-%dT%H:%M:%S.%6N'
Example:
logger = Logger.new($stdout) logger.add(Logger::INFO) # => I, [2022-05-07T17:04:32.318331 #20536] INFO -- : nil
You can set a different format using method datetime_format=
.
The message is an optional argument to an entry method:
logger = Logger.new($stdout) logger.add(Logger::INFO, 'My message') # => I, [2022-05-07T18:15:37.647581 #20536] INFO -- : My message
For the default entry formatter, Logger::Formatter
, the message object may be:
A string: used as-is.
An Exception: message.message
is used.
Anything else: message.inspect
is used.
Note: Logger::Formatter
does not escape or sanitize the message passed to it. Developers should be aware that malicious data (user input) may be in the message, and should explicitly escape untrusted data.
You can use a custom formatter to escape message data; see the example at formatter=.
The program name is an optional argument to an entry method:
logger = Logger.new($stdout) logger.add(Logger::INFO, 'My message', 'mung') # => I, [2022-05-07T18:17:38.084716 #20536] INFO -- mung: My message
The default program name for a new logger may be set in the call to Logger.new
via optional keyword argument progname
:
logger = Logger.new('t.log', progname: 'mung')
The default program name for an existing logger may be set by a call to method progname=
:
logger.progname = 'mung'
The current program name may be retrieved with method progname:
logger.progname # => "mung"
The log level setting determines whether an entry is actually written to the log, based on the entry’s severity.
These are the defined severities (least severe to most severe):
logger = Logger.new($stdout) logger.add(Logger::DEBUG, 'Maximal debugging info') # => D, [2022-05-07T17:57:41.776220 #20536] DEBUG -- : Maximal debugging info logger.add(Logger::INFO, 'Non-error information') # => I, [2022-05-07T17:59:14.349167 #20536] INFO -- : Non-error information logger.add(Logger::WARN, 'Non-error warning') # => W, [2022-05-07T18:00:45.337538 #20536] WARN -- : Non-error warning logger.add(Logger::ERROR, 'Non-fatal error') # => E, [2022-05-07T18:02:41.592912 #20536] ERROR -- : Non-fatal error logger.add(Logger::FATAL, 'Fatal error') # => F, [2022-05-07T18:05:24.703931 #20536] FATAL -- : Fatal error logger.add(Logger::UNKNOWN, 'Most severe') # => A, [2022-05-07T18:07:54.657491 #20536] ANY -- : Most severe
The default initial level setting is Logger::DEBUG, the lowest level, which means that all entries are to be written, regardless of severity:
logger = Logger.new($stdout) logger.level # => 0 logger.add(0, "My message") # => D, [2022-05-11T15:10:59.773668 #20536] DEBUG -- : My message
You can specify a different setting in a new logger using keyword argument level
with an appropriate value:
logger = Logger.new($stdout, level: Logger::ERROR) logger = Logger.new($stdout, level: 'error') logger = Logger.new($stdout, level: :error) logger.level # => 3
With this level, entries with severity Logger::ERROR and higher are written, while those with lower severities are not written:
logger = Logger.new($stdout, level: Logger::ERROR) logger.add(3) # => E, [2022-05-11T15:17:20.933362 #20536] ERROR -- : nil logger.add(2) # Silent.
You can set the log level for an existing logger with method level=
:
logger.level = Logger::ERROR
These shorthand methods also set the level:
logger.debug! # => 0 logger.info! # => 1 logger.warn! # => 2 logger.error! # => 3 logger.fatal! # => 4
You can retrieve the log level with method level:
logger.level = Logger::ERROR logger.level # => 3
These methods return whether a given level is to be written:
logger.level = Logger::ERROR logger.debug? # => false logger.info? # => false logger.warn? # => false logger.error? # => true logger.fatal? # => true
File
Rotation By default, a log file is a single file that grows indefinitely (until explicitly closed); there is no file rotation.
To keep log files to a manageable size, you can use log file rotation, which uses multiple log files:
Each log file has entries for a non-overlapping time interval.
Only the most recent log file is open and active; the others are closed and inactive.
For size-based log file rotation, call Logger.new
with:
Argument logdev
as a file path.
Argument shift_age
with a positive integer: the number of log files to be in the rotation.
Argument shift_size
as a positive integer: the maximum size (in bytes) of each log file; defaults to 1048576 (1 megabyte).
Examples:
logger = Logger.new('t.log', 3) # Three 1-megabyte files. logger = Logger.new('t.log', 5, 10485760) # Five 10-megabyte files.
For these examples, suppose:
logger = Logger.new('t.log', 3)
Logging begins in the new log file, t.log
; the log file is “full” and ready for rotation when a new entry would cause its size to exceed shift_size
.
The first time t.log
is full:
t.log
is closed and renamed to t.log.0
.
A new file t.log
is opened.
The second time t.log
is full:
+t.log.0 is renamed as t.log.1
.
t.log
is closed and renamed to t.log.0
.
A new file t.log
is opened.
Each subsequent time that t.log
is full, the log files are rotated:
t.log.1
is removed.
+t.log.0 is renamed as t.log.1
.
t.log
is closed and renamed to t.log.0
.
A new file t.log
is opened.
For periodic rotation, call Logger.new
with:
Argument logdev
as a file path.
Argument shift_age
as a string period indicator.
Examples:
logger = Logger.new('t.log', 'daily') # Rotate log files daily. logger = Logger.new('t.log', 'weekly') # Rotate log files weekly. logger = Logger.new('t.log', 'monthly') # Rotate log files monthly.
Example:
logger = Logger.new('t.log', 'daily')
When the given period expires:
The base log file, t.log
is closed and renamed with a date-based suffix such as t.log.20220509
.
A new log file t.log
is opened.
Nothing is removed.
The default format for the suffix is '%Y%m%d'
, which produces a suffix similar to the one above. You can set a different format using create-time option shift_period_suffix
; see details and suggestions at Time#strftime
.
Raised when attempting to convert special float values (in particular Infinity
or NaN
) to numerical classes which don’t support them.
Float::INFINITY.to_r #=> FloatDomainError: Infinity
The global value false
is the only instance of class FalseClass
and represents a logically false value in boolean expressions. The class provides operators allowing false
to participate correctly in logical expressions.
Raised when Ruby can’t yield as requested.
A typical scenario is attempting to yield when no block is given:
def call_block yield 42 end call_block
raises the exception:
LocalJumpError: no block given (yield)
A more subtle example:
def get_me_a_return Proc.new { return 42 } end get_me_a_return.call
raises the exception:
LocalJumpError: unexpected return
Raised in case of a stack overflow.
def me_myself_and_i me_myself_and_i end me_myself_and_i
raises the exception:
SystemStackError: stack level too deep
Raised when given an invalid regexp expression.
Regexp.new("?")
raises the exception:
RegexpError: target of repeat operator is not specified: /?/
Raised when an invalid operation is attempted on a thread.
For example, when no other thread has been started:
Thread.stop
This will raises the following exception:
ThreadError: stopping only thread note: use sleep to stop forever
Raised when throw
is called with a tag which does not have corresponding catch
block.
throw "foo", "bar"
raises the exception:
UncaughtThrowError: uncaught throw "foo"
RubyGems adds the gem
method to allow activation of specific gem versions and overrides the require
method on Kernel
to make gems appear as if they live on the $LOAD_PATH
. See the documentation of these methods for further detail.
Monkey patch kernel to ensure that all ‘require` calls call the same method
The Kernel
module is included by class Object
, so its methods are available in every Ruby object.
The Kernel
instance methods are documented in class Object
while the module methods are documented here. These methods are called without a receiver and thus can be called in functional form:
sprintf "%.1f", 1.234 #=> "1.2"
Module Kernel provides methods that are useful for:
__callee__
: Returns the called name of the current method as a symbol.
__dir__
: Returns the path to the directory from which the current method is called.
__method__
: Returns the name of the current method as a symbol.
autoload?
: Returns the file to be loaded when the given module is referenced.
binding
: Returns a Binding
for the context at the point of call.
block_given?
: Returns true
if a block was passed to the calling method.
caller
: Returns the current execution stack as an array of strings.
caller_locations
: Returns the current execution stack as an array of Thread::Backtrace::Location
objects.
class
: Returns the class of self
.
frozen?
: Returns whether self
is frozen.
global_variables
: Returns an array of global variables as symbols.
local_variables
: Returns an array of local variables as symbols.
test
: Performs specified tests on the given single file or pair of files.
abort
: Exits the current process after printing the given arguments.
at_exit
: Executes the given block when the process exits.
exit
: Exits the current process after calling any registered at_exit
handlers.
exit!
: Exits the current process without calling any registered at_exit
handlers.
catch
: Executes the given block, possibly catching a thrown object.
raise
(aliased as fail
): Raises an exception based on the given arguments.
throw
: Returns from the active catch block waiting for the given tag.
::pp
: Prints the given objects in pretty form.
gets
: Returns and assigns to $_
the next line from the current input.
open
: Creates an IO
object connected to the given stream, file, or subprocess.
p
: Prints the given objects’ inspect output to the standard output.
print
: Prints the given objects to standard output without a newline.
printf
: Prints the string resulting from applying the given format string to any additional arguments.
putc
: Equivalent to <tt.$stdout.putc(object)</tt> for the given object.
puts
: Equivalent to $stdout.puts(*objects)
for the given objects.
readline
: Similar to gets
, but raises an exception at the end of file.
readlines
: Returns an array of the remaining lines from the current input.
lambda
: Returns a lambda proc for the given block.
set_trace_func
: Sets the given proc as the handler for tracing, or disables tracing if given nil
.
trace_var
: Starts tracing assignments to the given global variable.
untrace_var
: Disables tracing of assignments to the given global variable.
`command`: Returns the standard output of running command
in a subshell.
exec
: Replaces current process with a new process.
fork
: Forks the current process into two processes.
spawn
: Executes the given command and returns its pid without waiting for completion.
system
: Executes the given command in a subshell.
autoload
: Registers the given file to be loaded when the given constant is first referenced.
load
: Loads the given Ruby file.
require
: Loads the given Ruby file unless it has already been loaded.
require_relative
: Loads the Ruby file path relative to the calling file, unless it has already been loaded.
tap
: Yields self
to the given block; returns self
.
then
(aliased as yield_self
): Yields self
to the block and returns the result of the block.
rand
: Returns a pseudo-random floating point number strictly between 0.0 and 1.0.
srand
: Seeds the pseudo-random number generator with the given number.
eval
: Evaluates the given string as Ruby code.
loop
: Repeatedly executes the given block.
sleep
: Suspends the current thread for the given number of seconds.
sprintf
(aliased as format
): Returns the string resulting from applying the given format string to any additional arguments.
syscall
: Runs an operating system call.
trap
: Specifies the handling of system signals.
warn
: Issue a warning based on the given messages and options.
Module Enumerable provides methods that are useful to a collection class for:
These methods return information about the Enumerable other than the elements themselves:
include?
, member?
: Returns true
if self == object
, false
otherwise.
all?
: Returns true
if all elements meet a specified criterion; false
otherwise.
any?
: Returns true
if any element meets a specified criterion; false
otherwise.
none?
: Returns true
if no element meets a specified criterion; false
otherwise.
one?
: Returns true
if exactly one element meets a specified criterion; false
otherwise.
count
: Returns the count of elements, based on an argument or block criterion, if given.
tally
: Returns a new Hash containing the counts of occurrences of each element.
These methods return entries from the Enumerable, without modifying it:
Leading, trailing, or all elements:
first
: Returns the first element or leading elements.
take
: Returns a specified number of leading elements.
drop
: Returns a specified number of trailing elements.
take_while
: Returns leading elements as specified by the given block.
drop_while
: Returns trailing elements as specified by the given block.
Minimum and maximum value elements:
min
: Returns the elements whose values are smallest among the elements, as determined by <=>
or a given block.
max
: Returns the elements whose values are largest among the elements, as determined by <=>
or a given block.
minmax
: Returns a 2-element Array containing the smallest and largest elements.
min_by
: Returns the smallest element, as determined by the given block.
max_by
: Returns the largest element, as determined by the given block.
minmax_by
: Returns the smallest and largest elements, as determined by the given block.
Groups, slices, and partitions:
group_by
: Returns a Hash that partitions the elements into groups.
partition
: Returns elements partitioned into two new Arrays, as determined by the given block.
slice_after
: Returns a new Enumerator whose entries are a partition of self
, based either on a given object
or a given block.
slice_before
: Returns a new Enumerator whose entries are a partition of self
, based either on a given object
or a given block.
slice_when
: Returns a new Enumerator whose entries are a partition of self
based on the given block.
chunk
: Returns elements organized into chunks as specified by the given block.
chunk_while
: Returns elements organized into chunks as specified by the given block.
These methods return elements that meet a specified criterion:
find_all
, filter
, select
: Returns elements selected by the block.
find_index
: Returns the index of an element selected by a given object or block.
reject
: Returns elements not rejected by the block.
uniq
: Returns elements that are not duplicates.
These methods return elements in sorted order:
sort
: Returns the elements, sorted by <=>
or the given block.
sort_by
: Returns the elements, sorted by the given block.
each_entry
: Calls the block with each successive element (slightly different from each).
each_with_index
: Calls the block with each successive element and its index.
each_with_object
: Calls the block with each successive element and a given object.
each_slice
: Calls the block with successive non-overlapping slices.
each_cons
: Calls the block with successive overlapping slices. (different from each_slice
).
reverse_each
: Calls the block with each successive element, in reverse order.
filter_map
: Returns truthy objects returned by the block.
flat_map
, collect_concat
: Returns flattened objects returned by the block.
grep
: Returns elements selected by a given object or objects returned by a given block.
grep_v
: Returns elements selected by a given object or objects returned by a given block.
reduce
, inject
: Returns the object formed by combining all elements.
sum
: Returns the sum of the elements, using method +
.
zip
: Combines each element with elements from other enumerables; returns the n-tuples or calls the block with each.
cycle
: Calls the block with each element, cycling repeatedly.
To use module Enumerable in a collection class:
Include it:
include Enumerable
Implement method #each
which must yield successive elements of the collection. The method will be called by almost any Enumerable method.
Example:
class Foo include Enumerable def each yield 1 yield 1, 2 yield end end Foo.new.each_entry{ |element| p element }
Output:
1 [1, 2] nil
These Ruby core classes include (or extend) Enumerable:
These Ruby standard library classes include Enumerable:
Virtually all methods in Enumerable call method #each
in the including class:
Hash#each
yields the next key-value pair as a 2-element Array.
Struct#each
yields the next name-value pair as a 2-element Array.
For the other classes above, #each
yields the next object from the collection.
The example code snippets for the Enumerable methods:
Always show the use of one or more Array-like classes (often Array itself).
Sometimes show the use of a Hash-like class. For some methods, though, the usage would not make sense, and so it is not shown. Example: tally
would find exactly one of each Hash entry.
Ruby exception objects are subclasses of Exception
. However, operating systems typically report errors using plain integers. Module
Errno
is created dynamically to map these operating system errors to Ruby classes, with each error number generating its own subclass of SystemCallError
. As the subclass is created in module Errno
, its name will start Errno::
.
The names of the Errno::
classes depend on the environment in which Ruby runs. On a typical Unix or Windows platform, there are Errno
classes such as Errno::EACCES, Errno::EAGAIN, Errno::EINTR, and so on.
The integer operating system error number corresponding to a particular error is available as the class constant Errno::
error::Errno
.
Errno::EACCES::Errno #=> 13 Errno::EAGAIN::Errno #=> 11 Errno::EINTR::Errno #=> 4
The full list of operating system errors on your particular platform are available as the constants of Errno
.
Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ...
The Warning
module contains a single method named warn
, and the module extends itself, making Warning.warn
available. Warning.warn
is called for all warnings issued by Ruby. By default, warnings are printed to $stderr.
Changing the behavior of Warning.warn
is useful to customize how warnings are handled by Ruby, for instance by filtering some warnings, and/or outputting warnings somewhere other than $stderr.
If you want to change the behavior of Warning.warn
you should use +Warning.extend(MyNewModuleWithWarnMethod)+ and you can use ‘super` to get the default behavior of printing the warning to $stderr.
Example:
module MyWarningFilter def warn(message, category: nil, **kwargs) if /some warning I want to ignore/.match?(message) # ignore else super end end end Warning.extend MyWarningFilter
You should never redefine Warning#warn
(the instance method), as that will then no longer provide a way to use the default behavior.
The warning
gem provides convenient ways to customize Warning.warn
.