Raised when a file required (a Ruby
script, extension library, …) fails to load.
require 'this/file/does/not/exist'
raises the exception:
LoadError: no such file to load -- this/file/does/not/exist
for RubyGems without Bundler
environment. If loading library is not part of the default gems and the bundled gems, warn it.
Raised when a given name is invalid or undefined.
puts foo
raises the exception:
NameError: undefined local variable or method `foo' for main:Object
Since constant names must start with a capital:
Integer.const_set :answer, 42
raises the exception:
NameError: wrong constant name answer
Raised when a method is called on a receiver which doesn’t have it defined and also fails to respond with method_missing
.
"hello".to_ary
raises the exception:
NoMethodError: undefined method `to_ary' for an instance of String
Raised when there is an attempt to modify a frozen object.
[1, 2, 3].freeze << 4
raises the exception:
FrozenError: can't modify frozen Array
Raised when memory allocation fails.
EncodingError
is the base class for encoding errors.
SystemCallError
is the base class for all low-level platform-dependent errors.
The errors available on the current platform are subclasses of SystemCallError
and are defined in the Errno
module.
File.open("does/not/exist")
raises the exception:
Errno::ENOENT: No such file or directory - does/not/exist
DateTime
A subclass of Date
that easily handles date, hour, minute, second, and offset.
DateTime
class is considered deprecated. Use Time
class.
DateTime
does not consider any leap seconds, does not track any summer time rules.
A DateTime
object is created with DateTime::new
, DateTime::jd
, DateTime::ordinal
, DateTime::commercial
, DateTime::parse
, DateTime::strptime
, DateTime::now
, Time#to_datetime
, etc.
require 'date' DateTime.new(2001,2,3,4,5,6) #=> #<DateTime: 2001-02-03T04:05:06+00:00 ...>
The last element of day, hour, minute, or second can be a fractional number. The fractional number’s precision is assumed at most nanosecond.
DateTime.new(2001,2,3.5) #=> #<DateTime: 2001-02-03T12:00:00+00:00 ...>
An optional argument, the offset, indicates the difference between the local time and UTC. For example, Rational(3,24)
represents ahead of 3 hours of UTC, Rational(-5,24)
represents behind of 5 hours of UTC. The offset should be -1 to +1, and its precision is assumed at most second. The default value is zero (equals to UTC).
DateTime.new(2001,2,3,4,5,6,Rational(3,24)) #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>
The offset also accepts string form:
DateTime.new(2001,2,3,4,5,6,'+03:00') #=> #<DateTime: 2001-02-03T04:05:06+03:00 ...>
An optional argument, the day of calendar reform (start
), denotes a Julian day number, which should be 2298874 to 2426355 or negative/positive infinity. The default value is Date::ITALY
(2299161=1582-10-15).
A DateTime
object has various methods. See each reference.
d = DateTime.parse('3rd Feb 2001 04:05:06+03:30') #=> #<DateTime: 2001-02-03T04:05:06+03:30 ...> d.hour #=> 4 d.min #=> 5 d.sec #=> 6 d.offset #=> (7/48) d.zone #=> "+03:30" d += Rational('1.5') #=> #<DateTime: 2001-02-04%16:05:06+03:30 ...> d = d.new_offset('+09:00') #=> #<DateTime: 2001-02-04%21:35:06+09:00 ...> d.strftime('%I:%M:%S %p') #=> "09:35:06 PM" d > DateTime.new(1999) #=> true
DateTime
and when should you use Time
? It’s a common misconception that William Shakespeare and Miguel de Cervantes died on the same day in history - so much so that UNESCO named April 23 as World Book Day because of this fact. However, because England hadn’t yet adopted the Gregorian Calendar Reform (and wouldn’t until 1752) their deaths are actually 10 days apart. Since Ruby’s Time
class implements a proleptic Gregorian calendar and has no concept of calendar reform there’s no way to express this with Time
objects. This is where DateTime
steps in:
shakespeare = DateTime.iso8601('1616-04-23', Date::ENGLAND) #=> Tue, 23 Apr 1616 00:00:00 +0000 cervantes = DateTime.iso8601('1616-04-23', Date::ITALY) #=> Sat, 23 Apr 1616 00:00:00 +0000
Already you can see something is weird - the days of the week are different. Taking this further:
cervantes == shakespeare #=> false (shakespeare - cervantes).to_i #=> 10
This shows that in fact they died 10 days apart (in reality 11 days since Cervantes died a day earlier but was buried on the 23rd). We can see the actual date of Shakespeare’s death by using the gregorian
method to convert it:
shakespeare.gregorian #=> Tue, 03 May 1616 00:00:00 +0000
So there’s an argument that all the celebrations that take place on the 23rd April in Stratford-upon-Avon are actually the wrong date since England is now using the Gregorian calendar. You can see why when we transition across the reform date boundary:
# start off with the anniversary of Shakespeare's birth in 1751 shakespeare = DateTime.iso8601('1751-04-23', Date::ENGLAND) #=> Tue, 23 Apr 1751 00:00:00 +0000 # add 366 days since 1752 is a leap year and April 23 is after February 29 shakespeare + 366 #=> Thu, 23 Apr 1752 00:00:00 +0000 # add another 365 days to take us to the anniversary in 1753 shakespeare + 366 + 365 #=> Fri, 04 May 1753 00:00:00 +0000
As you can see, if we’re accurately tracking the number of solar years since Shakespeare’s birthday then the correct anniversary date would be the 4th May and not the 23rd April.
So when should you use DateTime
in Ruby
and when should you use Time
? Almost certainly you’ll want to use Time
since your app is probably dealing with current dates and times. However, if you need to deal with dates and times in a historical context you’ll want to use DateTime
to avoid making the same mistakes as UNESCO. If you also have to deal with timezones then best of luck - just bear in mind that you’ll probably be dealing with local solar times, since it wasn’t until the 19th century that the introduction of the railways necessitated the need for Standard Time and eventually timezones.
A Time
object represents a date and time:
Time.new(2000, 1, 1, 0, 0, 0) # => 2000-01-01 00:00:00 -0600
Although its value can be expressed as a single numeric (see Epoch Seconds below), it can be convenient to deal with the value by parts:
t = Time.new(-2000, 1, 1, 0, 0, 0.0) # => -2000-01-01 00:00:00 -0600 t.year # => -2000 t.month # => 1 t.mday # => 1 t.hour # => 0 t.min # => 0 t.sec # => 0 t.subsec # => 0 t = Time.new(2000, 12, 31, 23, 59, 59.5) # => 2000-12-31 23:59:59.5 -0600 t.year # => 2000 t.month # => 12 t.mday # => 31 t.hour # => 23 t.min # => 59 t.sec # => 59 t.subsec # => (1/2)
Epoch seconds is the exact number of seconds (including fractional subseconds) since the Unix Epoch, January 1, 1970.
You can retrieve that value exactly using method Time.to_r
:
Time.at(0).to_r # => (0/1) Time.at(0.999999).to_r # => (9007190247541737/9007199254740992)
Other retrieval methods such as Time#to_i
and Time#to_f
may return a value that rounds or truncates subseconds.
A Time
object derived from the system clock (for example, by method Time.now
) has the resolution supported by the system.
Time
implementation uses a signed 63 bit integer, Integer
, or Rational
. It is a number of nanoseconds since the Epoch. The signed 63 bit integer can represent 1823-11-12 to 2116-02-20. When Integer
or Rational
is used (before 1823, after 2116, under nanosecond), Time
works slower than when the signed 63 bit integer is used.
Ruby
uses the C function localtime
and gmtime
to map between the number and 6-tuple (year,month,day,hour,minute,second). localtime
is used for local time and “gmtime” is used for UTC.
Integer
and Rational
has no range limit, but the localtime and gmtime has range limits due to the C types time_t
and struct tm
. If that limit is exceeded, Ruby
extrapolates the localtime function.
The Time
class always uses the Gregorian calendar. I.e. the proleptic Gregorian calendar is used. Other calendars, such as Julian calendar, are not supported.
time_t
can represent 1901-12-14 to 2038-01-19 if it is 32 bit signed integer, -292277022657-01-27 to 292277026596-12-05 if it is 64 bit signed integer. However localtime
on some platforms doesn’t supports negative time_t
(before 1970).
struct tm
has tm_year member to represent years. (tm_year = 0
means the year 1900.) It is defined as int
in the C standard. tm_year can represent between -2147481748 to 2147485547 if int
is 32 bit.
Ruby
supports leap seconds as far as if the C function localtime
and gmtime
supports it. They use the tz database in most Unix systems. The tz database has timezones which supports leap seconds. For example, “Asia/Tokyo” doesn’t support leap seconds but “right/Asia/Tokyo” supports leap seconds. So, Ruby
supports leap seconds if the TZ environment variable is set to “right/Asia/Tokyo” in most Unix systems.
All of these examples were done using the EST timezone which is GMT-5.
Time
Instance You can create a new instance of Time
with Time.new
. This will use the current system time. Time.now
is an alias for this. You can also pass parts of the time to Time.new
such as year, month, minute, etc. When you want to construct a time this way you must pass at least a year. If you pass the year with nothing else time will default to January 1 of that year at 00:00:00 with the current system timezone. Here are some examples:
Time.new(2002) #=> 2002-01-01 00:00:00 -0500 Time.new(2002, 10) #=> 2002-10-01 00:00:00 -0500 Time.new(2002, 10, 31) #=> 2002-10-31 00:00:00 -0500
You can pass a UTC offset:
Time.new(2002, 10, 31, 2, 2, 2, "+02:00") #=> 2002-10-31 02:02:02 +0200
zone = timezone("Europe/Athens") # Eastern European Time, UTC+2 Time.new(2002, 10, 31, 2, 2, 2, zone) #=> 2002-10-31 02:02:02 +0200
You can also use Time.local
and Time.utc
to infer local and UTC timezones instead of using the current system setting.
You can also create a new time using Time.at
which takes the number of seconds (with subsecond) since the Unix Epoch.
Time.at(628232400) #=> 1989-11-28 00:00:00 -0500
Time
Once you have an instance of Time
there is a multitude of things you can do with it. Below are some examples. For all of the following examples, we will work on the assumption that you have done the following:
t = Time.new(1993, 02, 24, 12, 0, 0, "+09:00")
Was that a monday?
t.monday? #=> false
What year was that again?
t.year #=> 1993
Was it daylight savings at the time?
t.dst? #=> false
What’s the day a year later?
t + (60*60*24*365) #=> 1994-02-24 12:00:00 +0900
How many seconds was that since the Unix Epoch?
t.to_i #=> 730522800
You can also do standard functions like compare two times.
t1 = Time.new(2010) t2 = Time.new(2011) t1 == t2 #=> false t1 == t1 #=> true t1 < t2 #=> true t1 > t2 #=> false Time.new(2010,10,31).between?(t1, t2) #=> true
First, what’s elsewhere. Class
Time
:
Inherits from class Object.
Includes module Comparable.
Here, class Time
provides methods that are useful for:
::new
: Returns a new time from specified arguments (year, month, etc.), including an optional timezone value.
::local
(aliased as ::mktime
): Same as ::new
, except the timezone is the local timezone.
::utc
(aliased as ::gm
): Same as ::new
, except the timezone is UTC.
::at
: Returns a new time based on seconds since epoch.
::now
: Returns a new time based on the current system time.
+
(plus): Returns a new time increased by the given number of seconds.
-
(minus): Returns a new time decreased by the given number of seconds.
year
: Returns the year of the time.
hour
: Returns the hours value for the time.
min
: Returns the minutes value for the time.
sec
: Returns the seconds value for the time.
usec
(aliased as tv_usec
): Returns the number of microseconds in the subseconds value of the time.
nsec
(aliased as tv_nsec
: Returns the number of nanoseconds in the subsecond part of the time.
subsec
: Returns the subseconds value for the time.
wday
: Returns the integer weekday value of the time (0 == Sunday).
yday
: Returns the integer yearday value of the time (1 == January 1).
hash
: Returns the integer hash value for the time.
utc_offset
(aliased as gmt_offset
and gmtoff
): Returns the offset in seconds between time and UTC.
to_f
: Returns the float number of seconds since epoch for the time.
to_i
(aliased as tv_sec
): Returns the integer number of seconds since epoch for the time.
to_r
: Returns the Rational
number of seconds since epoch for the time.
zone
: Returns a string representation of the timezone of the time.
dst?
(aliased as isdst
): Returns whether the time is DST (daylight saving time).
sunday?
: Returns whether the time is a Sunday.
monday?
: Returns whether the time is a Monday.
tuesday?
: Returns whether the time is a Tuesday.
wednesday?
: Returns whether the time is a Wednesday.
thursday?
: Returns whether the time is a Thursday.
friday?
: Returns whether time is a Friday.
saturday?
: Returns whether the time is a Saturday.
inspect
: Returns the time in detail as a string.
strftime
: Returns the time as a string, according to a given format.
to_a
: Returns a 10-element array of values from the time.
to_s
: Returns a string representation of the time.
getutc
(aliased as getgm
): Returns a new time converted to UTC.
getlocal
: Returns a new time converted to local time.
localtime
: Converts time to local time in place.
deconstruct_keys
: Returns a hash of time components used in pattern-matching.
round
:Returns a new time with subseconds rounded.
ceil
: Returns a new time with subseconds raised to a ceiling.
floor
: Returns a new time with subseconds lowered to a floor.
For the forms of argument zone
, see Timezone Specifiers.
Certain Time
methods accept arguments that specify timezones:
Time.at
: keyword argument in:
.
Time.new
: positional argument zone
or keyword argument in:
.
Time.now
: keyword argument in:
.
Time#getlocal
: positional argument zone
.
Time#localtime
: positional argument zone
.
The value given with any of these must be one of the following (each detailed below):
The zone value may be a string offset from UTC in the form '+HH:MM'
or '-HH:MM'
, where:
HH
is the 2-digit hour in the range 0..23
.
MM
is the 2-digit minute in the range 0..59
.
Examples:
t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC Time.at(t, in: '-23:59') # => 1999-12-31 20:16:01 -2359 Time.at(t, in: '+23:59') # => 2000-01-02 20:14:01 +2359
The zone value may be a letter in the range 'A'..'I'
or 'K'..'Z'
; see List of military time zones:
t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC Time.at(t, in: 'A') # => 2000-01-01 21:15:01 +0100 Time.at(t, in: 'I') # => 2000-01-02 05:15:01 +0900 Time.at(t, in: 'K') # => 2000-01-02 06:15:01 +1000 Time.at(t, in: 'Y') # => 2000-01-01 08:15:01 -1200 Time.at(t, in: 'Z') # => 2000-01-01 20:15:01 UTC
The zone value may be an integer number of seconds in the range -86399..86399
:
t = Time.utc(2000, 1, 1, 20, 15, 1) # => 2000-01-01 20:15:01 UTC Time.at(t, in: -86399) # => 1999-12-31 20:15:02 -235959 Time.at(t, in: 86399) # => 2000-01-02 20:15:00 +235959
The zone value may be an object responding to certain timezone methods, an instance of Timezone and TZInfo for example.
The timezone methods are:
local_to_utc
:
Called when Time.new
is invoked with tz
as the value of positional argument zone
or keyword argument in:
.
a Time-like object in the UTC timezone.
utc_to_local
:
Called when Time.at
or Time.now
is invoked with tz
as the value for keyword argument in:
, and when Time#getlocal
or Time#localtime
is called with tz
as the value for positional argument zone
.
The UTC offset will be calculated as the difference between the original time and the returned object as an Integer
. If the object is in fixed offset, its utc_offset
is also counted.
a Time-like object in the local timezone.
A custom timezone class may have these instance methods, which will be called if defined:
abbr
:
Called when Time#strftime
is invoked with a format involving %Z
.
a string abbreviation for the timezone name.
dst?
:
Called when Time.at
or Time.now
is invoked with tz
as the value for keyword argument in:
, and when Time#getlocal
or Time#localtime
is called with tz
as the value for positional argument zone
.
whether the time is daylight saving time.
name
:
Called when Marshal.dump(t)
is invoked
none.
the string name of the timezone.
Time
-Like Objects A Time
-like object is a container object capable of interfacing with timezone libraries for timezone conversion.
The argument to the timezone conversion methods above will have attributes similar to Time
, except that timezone related attributes are meaningless.
The objects returned by local_to_utc
and utc_to_local
methods of the timezone object may be of the same class as their arguments, of arbitrary object classes, or of class Integer
.
For a returned class other than Integer
, the class must have the following methods:
year
mon
mday
hour
min
sec
isdst
to_i
For a returned Integer
, its components, decomposed in UTC, are interpreted as times in the specified timezone.
If the class (the receiver of class methods, or the class of the receiver of instance methods) has find_timezone
singleton method, this method is called to achieve the corresponding timezone object from a timezone name.
For example, using Timezone:
class TimeWithTimezone < Time require 'timezone' def self.find_timezone(z) = Timezone[z] end TimeWithTimezone.now(in: "America/New_York") #=> 2023-12-25 00:00:00 -0500 TimeWithTimezone.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500
Or, using TZInfo:
class TimeWithTZInfo < Time require 'tzinfo' def self.find_timezone(z) = TZInfo::Timezone.get(z) end TimeWithTZInfo.now(in: "America/New_York") #=> 2023-12-25 00:00:00 -0500 TimeWithTZInfo.new("2023-12-25 America/New_York") #=> 2023-12-25 00:00:00 -0500
You can define this method per subclasses, or on the toplevel Time
class.
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 and 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.
These methods discard buffers and the Encoding::Converter
instances used for that IO.
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
Class
IO supports line-oriented input and output
Class
IO supports line-oriented input for files and IO streams
You can read lines from a file using these methods:
IO.foreach
: Reads each line and passes it to the given block.
IO.readlines
: Reads and returns all lines in an array.
For each of these methods:
You can specify open options.
Line parsing depends on the effective line separator; see Line Separator.
The length of each returned line depends on the effective line limit; see Line Limit.
You can read lines from an IO stream 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.
For each of these methods:
Reading may begin mid-line, depending on the stream’s position; see Position.
Line parsing depends on the effective line separator; see Line Separator.
The length of each returned line depends on the effective line limit; see Line Limit.
Each of the line input methods uses a line separator: the string that determines what is considered a line; it is sometimes called the input record separator.
The default line separator is taken from global variable $/
, whose initial value is "\n"
.
Generally, the line to be read next is all data from the current position to the next line separator (but see Special Line Separator Values):
f = File.new('t.txt') # Method gets with no sep argument returns the next line, according to $/. 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 use a different line separator by passing argument sep
:
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
Or by setting global variable $/
:
f = File.new('t.txt') $/ = 'l' f.gets # => "First l" f.gets # => "ine\nSecond l" f.gets # => "ine\n\nFourth l" f.close
Each of the line input methods accepts two special values for parameter sep
:
nil
: The entire stream is to be read (“slurped”) 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 to be 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 the line input methods uses an integer line limit, which restricts the number of bytes that may be returned. (A multi-byte character will not be split, and so a returned line may be slightly longer than the limit).
The default limit value is -1
; any negative limit value means that there is no limit.
If there is no limit, 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 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:
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 effective line separator:
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 write to an IO stream line-by-line using this method:
IO#puts
: Writes objects to the stream.
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
.
This library provides the Set
class, which implements 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
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
: Merges the elements of each given enumerable 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| _ }
Ruby
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.
Creates and manages pseudo terminals (PTYs). See also en.wikipedia.org/wiki/Pseudo_terminal
PTY
allows you to allocate new terminals using ::open
or ::spawn
a new terminal with a specific command.
In this example we will change the buffering type in the factor
command, assuming that factor uses stdio for stdout buffering.
If IO.pipe
is used instead of PTY.open
, this code deadlocks because factor’s stdout is fully buffered.
# start by requiring the standard library PTY require 'pty' master, slave = PTY.open read, write = IO.pipe pid = spawn("factor", :in=>read, :out=>slave) read.close # we dont need the read slave.close # or the slave # pipe "42" to the factor command write.puts "42" # output the response from factor p master.gets #=> "42: 2 3 7\n" # pipe "144" to factor and print out the response write.puts "144" p master.gets #=> "144: 2 2 2 2 3 3\n" write.close # close the pipe # The result of read operation when pty slave is closed is platform # dependent. ret = begin master.gets # FreeBSD returns nil. rescue Errno::EIO # GNU/Linux raises EIO. nil end p ret #=> nil
© Copyright 1998 by Akinori Ito.
This software may be redistributed freely for this purpose, in full or in part, provided that this entire copyright notice is included on any copies of this software and applications and derivations thereof.
This software is provided on an “as is” basis, without warranty of any kind, either expressed or implied, as to any matter including, but not limited to warranty of fitness of purpose, or merchantability, or results obtained from use of this software.
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'
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
ARGV
The ARGF object works with the array at global variable ARGV
to make $stdin
and file streams available in the Ruby
program:
ARGV may be thought of as the argument vector array.
Initially, it contains the command-line arguments and options that are passed to the Ruby
program; the program can modify that array as it likes.
ARGF may be thought of as the argument files object.
It can access file streams and/or the $stdin
stream, based on what it finds in ARGV
. This provides a convenient way for the command line to specify streams for a Ruby
program to read.
ARGF may read from source streams, which at any particular time are determined by the content of ARGV
.
When the very first ARGF read occurs with an empty ARGV
([]
), the source is $stdin
:
File t.rb
:
p ['ARGV', ARGV] p ['ARGF.read', ARGF.read]
Commands and outputs (see below for the content of files foo.txt
and bar.txt
):
$ echo "Open the pod bay doors, Hal." | ruby t.rb ["ARGV", []] ["ARGF.read", "Open the pod bay doors, Hal.\n"] $ cat foo.txt bar.txt | ruby t.rb ["ARGV", []] ["ARGF.read", "Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"]
Many examples here assume the existence of files foo.txt
and bar.txt
:
$ cat foo.txt Foo 0 Foo 1 $ cat bar.txt Bar 0 Bar 1 Bar 2 Bar 3
ARGV
For any ARGF read except the simplest case (that is, except for the very first ARGF read with an empty ARGV
), the sources are found in ARGV
.
ARGF assumes that each element in array ARGV
is a potential source, and is one of:
The string path to a file that may be opened as a stream.
The character '-'
, meaning stream $stdin
.
Each element that is not one of these should be removed from ARGV
before ARGF accesses that source.
In the following example:
Filepaths foo.txt
and bar.txt
may be retained as potential sources.
Options --xyzzy
and --mojo
should be removed.
Example:
File t.rb
:
# Print arguments (and options, if any) found on command line. p ['ARGV', ARGV]
Command and output:
$ ruby t.rb --xyzzy --mojo foo.txt bar.txt ["ARGV", ["--xyzzy", "--mojo", "foo.txt", "bar.txt"]]
ARGF’s stream access considers the elements of ARGV
, left to right:
File t.rb
:
p "ARGV: #{ARGV}" p "Line: #{ARGF.read}" # Read everything from all specified streams.
Command and output:
$ ruby t.rb foo.txt bar.txt "ARGV: [\"foo.txt\", \"bar.txt\"]" "Read: Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"
Because the value at ARGV
is an ordinary array, you can manipulate it to control which sources ARGF considers:
If you remove an element from ARGV
, ARGF will not consider the corresponding source.
If you add an element to ARGV
, ARGF will consider the corresponding source.
Each element in ARGV
is removed when its corresponding source is accessed; when all sources have been accessed, the array is empty:
File t.rb
:
until ARGV.empty? && ARGF.eof? p "ARGV: #{ARGV}" p "Line: #{ARGF.readline}" # Read each line from each specified stream. end
Command and output:
$ ruby t.rb foo.txt bar.txt "ARGV: [\"foo.txt\", \"bar.txt\"]" "Line: Foo 0\n" "ARGV: [\"bar.txt\"]" "Line: Foo 1\n" "ARGV: [\"bar.txt\"]" "Line: Bar 0\n" "ARGV: []" "Line: Bar 1\n" "ARGV: []" "Line: Bar 2\n" "ARGV: []" "Line: Bar 3\n"
ARGV
The ARGV
array may contain filepaths the specify sources for ARGF reading.
This program prints what it reads from files at the paths specified on the command line:
File t.rb
:
p ['ARGV', ARGV] # Read and print all content from the specified sources. p ['ARGF.read', ARGF.read]
Command and output:
$ ruby t.rb foo.txt bar.txt ["ARGV", [foo.txt, bar.txt] ["ARGF.read", "Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"]
$stdin
in ARGV
To specify stream $stdin
in ARGV
, us the character '-'
:
File t.rb
:
p ['ARGV', ARGV] p ['ARGF.read', ARGF.read]
Command and output:
$ echo "Open the pod bay doors, Hal." | ruby t.rb - ["ARGV", ["-"]] ["ARGF.read", "Open the pod bay doors, Hal.\n"]
When no character '-'
is given, stream $stdin
is ignored (exception: see Specifying $stdin in ARGV):
Command and output:
$ echo "Open the pod bay doors, Hal." | ruby t.rb foo.txt bar.txt "ARGV: [\"foo.txt\", \"bar.txt\"]" "Read: Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"
ARGV
For an ARGF reader, ARGV
may contain any mixture of filepaths and character '-'
, including repetitions.
ARGV
The running Ruby
program may make any modifications to the ARGV
array; the current value of ARGV
affects ARGF reading.
ARGV
For an empty ARGV
, an ARGF read method either returns nil
or raises an exception, depending on the specific method.
As seen above, method ARGF#read
reads the content of all sources into a single string. Other ARGF methods provide other ways to access that content; these include:
Codepoint access: each_codepoint
.
Source access: read
, read_nonblock
, readpartial
.
ARGF includes module Enumerable
. Virtually all methods in Enumerable call method #each
in the including class.
Note well: In ARGF, method each
returns data from the sources, not from ARGV
; therefore, for example, ARGF#entries
returns an array of lines from the sources, not an array of the strings from ARGV
:
File t.rb
:
p ['ARGV', ARGV] p ['ARGF.entries', ARGF.entries]
Command and output:
$ ruby t.rb foo.txt bar.txt ["ARGV", ["foo.txt", "bar.txt"]] ["ARGF.entries", ["Foo 0\n", "Foo 1\n", "Bar 0\n", "Bar 1\n", "Bar 2\n", "Bar 3\n"]]
If inplace mode is in effect, ARGF may write to target streams, which at any particular time are determined by the content of ARGV.
Methods about inplace mode:
Methods for writing:
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
Ruby
in HTML 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>
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.