On this page
Preview Ruby 4.1 is a preview. It can change before the final release. Switch to Ruby 4.0 →
ARGF
ARGF and 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
$stdinstream, based on what it finds inARGV. This provides a convenient way for the command line to specify streams for a Ruby program to read.
Reading
ARGF may read from source streams, which at any particular time are determined by the content of ARGV.
Simplest Case
When the very first ARGF read occurs with an empty ARGV ([]), the source is $stdin:
-
File
t.rb:Examplep ['ARGV', ARGV] p ['ARGF.read', ARGF.read]
-
Commands and outputs (see below for the content of files
foo.txtandbar.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"]
About the Examples
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
Sources in 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.txtandbar.txtmay be retained as potential sources. -
Options
--xyzzyand--mojoshould be removed.
Example:
-
File
t.rb:Example# 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:Examplep "ARGV: #{ARGV}" p "Read: #{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:Exampleuntil 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"
Filepaths in 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:Examplep ['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"]
Specifying $stdin in ARGV
To specify stream $stdin in ARGV, us the character '-':
-
File
t.rb:Examplep ['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.
-
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"
Mixtures and Repetitions in ARGV
For an ARGF reader, ARGV may contain any mixture of filepaths and character '-', including repetitions.
Modifications to ARGV
The running Ruby program may make any modifications to the ARGV array; the current value of ARGV affects ARGF reading.
Empty ARGV
For an empty ARGV, an ARGF read method either returns nil or raises an exception, depending on the specific method.
More Read Methods
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.
About Enumerable
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:Examplep ['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"]]
Writing
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: