class ARGF - RDoc Documentation

# class 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 `$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.

## 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`:

      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"]

### 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.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"

#### 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`:

      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"]

#### Specifying `$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"

#### 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:

- Byte access: `each_byte`, `getbyte`, `readbyte`.

- Character access: `each_char`, `getc`, `readchar`.

- Codepoint access: `each_codepoint`.

- Line access: `each_line`, `gets`, `readline`, `readlines`.

- 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`:

      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"]]

## 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:

- `inplace_mode`

- `inplace_mode=`

- `to_write_io`

Methods for writing:

- `print`

- `printf`

- `putc`

- `puts`

- `write`

### Public Instance Methods

argv → ARGV click to toggle source

Returns the `ARGV` array, which contains the arguments passed to your script, one per element.

For example:

    $ ruby argf.rb -v glark.txt

    ARGF.argv   #=> ["-v", "glark.txt"]

    static VALUE
    argf_argv(VALUE argf)
    {
        return ARGF.argv;
    }

binmode → ARGF click to toggle source

Puts `ARGF` into binary mode. Once a stream is in binary mode, it cannot be reset to non-binary mode. This option has the following effects:

- Newline conversion is disabled.

- `Encoding` conversion is disabled.

- Content is treated as ASCII-8BIT.

    static VALUE
    argf_binmode_m(VALUE argf)
    {
        ARGF.binmode = 1;
        next_argv();
        ARGF_FORWARD(0, 0);
        rb_io_ascii8bit_binmode(ARGF.current_file);
        return argf;
    }

binmode? → true or false click to toggle source

Returns true if `ARGF` is being read in binary mode; false otherwise. To enable binary mode use `ARGF.binmode`.

For example:

    ARGF.binmode?  #=> false
    ARGF.binmode
    ARGF.binmode?  #=> true

    static VALUE
    argf_binmode_p(VALUE argf)
    {
        return RBOOL(ARGF.binmode);
    }

close → ARGF click to toggle source

Closes the current file and skips to the next file in ARGV. If there are no more files to open, just closes the current file. STDIN will not be closed.

For example:

    $ ruby argf.rb foo bar

    ARGF.filename  #=> "foo"
    ARGF.close
    ARGF.filename  #=> "bar"
    ARGF.close

    static VALUE
    argf_close_m(VALUE argf)
    {
        next_argv();
        argf_close(argf);
        if (ARGF.next_p != -1) {
            ARGF.next_p = 1;
        }
        ARGF.lineno = 0;
        return argf;
    }

closed? → true or false click to toggle source

Returns true if the current file has been closed; false otherwise. Use `ARGF.close` to actually close the current file.

    static VALUE
    argf_closed(VALUE argf)
    {
        next_argv();
        ARGF_FORWARD(0, 0);
        return rb_io_closed_p(ARGF.current_file);
    }

each(sep=$/) {|line| block } → ARGF click to toggle source
each(sep=$/, limit) {|line| block } → ARGF
each(...) → an_enumerator

Returns an enumerator which iterates over each line (separated by sep, which defaults to your platform’s newline character) of each file in `ARGV`. If a block is supplied, each line in turn will be yielded to the block, otherwise an enumerator is returned. The optional limit argument is an `Integer` specifying the maximum length of each line; longer lines will be split according to this limit.

This method allows you to treat the files supplied on the command line as a single file consisting of the concatenation of each named file. After the last line of the first file has been returned, the first line of the second file is returned. The `ARGF.filename` and `ARGF.lineno` methods can be used to determine the filename of the current line and line number of the whole input, respectively.

For example, the following code prints out each line of each named file prefixed with its line number, displaying the filename once per file:

    ARGF.each_line do |line|
      puts ARGF.filename if ARGF.file.lineno == 1
      puts "#{ARGF.file.lineno}: #{line}"
    end

While the following code prints only the first file’s name at first, and the contents with line number counted through all named files.

    ARGF.each_line do |line|
      puts ARGF.filename if ARGF.lineno == 1
      puts "#{ARGF.lineno}: #{line}"
    end

    static VALUE
    argf_each_line(int argc, VALUE *argv, VALUE argf)
    {
        RETURN_ENUMERATOR(argf, argc, argv);
        FOREACH_ARGF() {
            argf_block_call_line(rb_intern("each_line"), argc, argv, argf);
        }
        return argf;
    }

Also aliased as: each_line
each_byte {|byte| block } → ARGF click to toggle source
each_byte → an_enumerator

Iterates over each byte of each file in `ARGV`. A byte is returned as an `Integer` in the range 0..255.

This method allows you to treat the files supplied on the command line as a single file consisting of the concatenation of each named file. After the last byte of the first file has been returned, the first byte of the second file is returned. The `ARGF.filename` method can be used to determine the filename of the current byte.

If no block is given, an enumerator is returned instead.

For example:

    ARGF.bytes.to_a  #=> [35, 32, ... 95, 10]

    static VALUE
    argf_each_byte(VALUE argf)
    {
        RETURN_ENUMERATOR(argf, 0, 0);
        FOREACH_ARGF() {
            argf_block_call(rb_intern("each_byte"), 0, 0, argf);
        }
        return argf;
    }

each_char {|char| block } → ARGF click to toggle source
each_char → an_enumerator

Iterates over each character of each file in `ARGF`.

This method allows you to treat the files supplied on the command line as a single file consisting of the concatenation of each named file. After the last character of the first file has been returned, the first character of the second file is returned. The `ARGF.filename` method can be used to determine the name of the file in which the current character appears.

If no block is given, an enumerator is returned instead.

    static VALUE
    argf_each_char(VALUE argf)
    {
        RETURN_ENUMERATOR(argf, 0, 0);
        FOREACH_ARGF() {
            argf_block_call(rb_intern("each_char"), 0, 0, argf);
        }
        return argf;
    }

each_codepoint {|codepoint| block } → ARGF click to toggle source
each_codepoint → an_enumerator

Iterates over each codepoint of each file in `ARGF`.

This method allows you to treat the files supplied on the command line as a single file consisting of the concatenation of each named file. After the last codepoint of the first file has been returned, the first codepoint of the second file is returned. The `ARGF.filename` method can be used to determine the name of the file in which the current codepoint appears.

If no block is given, an enumerator is returned instead.

    static VALUE
    argf_each_codepoint(VALUE argf)
    {
        RETURN_ENUMERATOR(argf, 0, 0);
        FOREACH_ARGF() {
            argf_block_call(rb_intern("each_codepoint"), 0, 0, argf);
        }
        return argf;
    }

each_line(*args)

Returns an enumerator which iterates over each line (separated by sep, which defaults to your platform’s newline character) of each file in `ARGV`. If a block is supplied, each line in turn will be yielded to the block, otherwise an enumerator is returned. The optional limit argument is an `Integer` specifying the maximum length of each line; longer lines will be split according to this limit.

This method allows you to treat the files supplied on the command line as a single file consisting of the concatenation of each named file. After the last line of the first file has been returned, the first line of the second file is returned. The `ARGF.filename` and `ARGF.lineno` methods can be used to determine the filename of the current line and line number of the whole input, respectively.

For example, the following code prints out each line of each named file prefixed with its line number, displaying the filename once per file:

    ARGF.each_line do |line|
      puts ARGF.filename if ARGF.file.lineno == 1
      puts "#{ARGF.file.lineno}: #{line}"
    end

While the following code prints only the first file’s name at first, and the contents with line number counted through all named files.

    ARGF.each_line do |line|
      puts ARGF.filename if ARGF.lineno == 1
      puts "#{ARGF.lineno}: #{line}"
    end

Alias for: each
eof → true or false click to toggle source

Returns true if the current file in `ARGF` is at end of file, i.e. it has no data to read. The stream must be opened for reading or an `IOError` will be raised.

    $ echo "eof" | ruby argf.rb

    ARGF.eof?                 #=> false
    3.times { ARGF.readchar }
    ARGF.eof?                 #=> false
    ARGF.readchar             #=> "\n"
    ARGF.eof?                 #=> true

    static VALUE
    argf_eof(VALUE argf)
    {
        next_argv();
        if (RTEST(ARGF.current_file)) {
            if (ARGF.init_p == 0) return Qtrue;
            next_argv();
            ARGF_FORWARD(0, 0);
            if (rb_io_eof(ARGF.current_file)) {
                return Qtrue;
            }
        }
        return Qfalse;
    }

Also aliased as: eof?
eof?()

Returns true if the current file in `ARGF` is at end of file, i.e. it has no data to read. The stream must be opened for reading or an `IOError` will be raised.

    $ echo "eof" | ruby argf.rb

    ARGF.eof?                 #=> false
    3.times { ARGF.readchar }
    ARGF.eof?                 #=> false
    ARGF.readchar             #=> "\n"
    ARGF.eof?                 #=> true

Alias for: eof
external_encoding → encoding click to toggle source

Returns the external encoding for files read from `ARGF` as an `Encoding` object. The external encoding is the encoding of the text as stored in a file. Contrast with `ARGF.internal_encoding`, which is the encoding used to represent this text within Ruby.

To set the external encoding use `ARGF.set_encoding`.

For example:

    ARGF.external_encoding  #=>  #<Encoding:UTF-8>

    static VALUE
    argf_external_encoding(VALUE argf)
    {
        return argf_encoding(argf, rb_io_external_encoding);
    }

file → IO or File object click to toggle source

Returns the current file as an `IO` or `File` object. `$stdin` is returned when the current file is STDIN.

For example:

    $ echo "foo" > foo
    $ echo "bar" > bar

    $ ruby argf.rb foo bar

    ARGF.file      #=> #<File:foo>
    ARGF.read(5)   #=> "foo\nb"
    ARGF.file      #=> #<File:bar>

    static VALUE
    argf_file(VALUE argf)
    {
        next_argv();
        return ARGF.current_file;
    }

filename → String click to toggle source

Returns the current filename. “-” is returned when the current file is STDIN.

For example:

    $ echo "foo" > foo
    $ echo "bar" > bar
    $ echo "glark" > glark

    $ ruby argf.rb foo bar glark

    ARGF.filename  #=> "foo"
    ARGF.read(5)   #=> "foo\nb"
    ARGF.filename  #=> "bar"
    ARGF.skip
    ARGF.filename  #=> "glark"

    static VALUE
    argf_filename(VALUE argf)
    {
        next_argv();
        return ARGF.filename;
    }

Also aliased as: path
fileno → integer click to toggle source

Returns an integer representing the numeric file descriptor for the current file. Raises an `ArgumentError` if there isn’t a current file.

    ARGF.fileno    #=> 3

    static VALUE
    argf_fileno(VALUE argf)
    {
        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream");
        }
        ARGF_FORWARD(0, 0);
        return rb_io_fileno(ARGF.current_file);
    }

Also aliased as: to_i
getbyte → Integer or nil click to toggle source

Gets the next 8-bit byte (0..255) from `ARGF`. Returns `nil` if called at the end of the stream.

For example:

    $ echo "foo" > file
    $ ruby argf.rb file

    ARGF.getbyte #=> 102
    ARGF.getbyte #=> 111
    ARGF.getbyte #=> 111
    ARGF.getbyte #=> 10
    ARGF.getbyte #=> nil

    static VALUE
    argf_getbyte(VALUE argf)
    {
        VALUE ch;

      retry:
        if (!next_argv()) return Qnil;
        if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
            ch = forward_current(rb_intern("getbyte"), 0, 0);
        }
        else {
            ch = rb_io_getbyte(ARGF.current_file);
        }
        if (NIL_P(ch) && ARGF.next_p != -1) {
            argf_close(argf);
            ARGF.next_p = 1;
            goto retry;
        }

        return ch;
    }

getc → String or nil click to toggle source

Reads the next character from `ARGF` and returns it as a `String`. Returns `nil` at the end of the stream.

`ARGF` treats the files named on the command line as a single file created by concatenating their contents. After returning the last character of the first file, it returns the first character of the second file, and so on.

For example:

    $ echo "foo" > file
    $ ruby argf.rb file

    ARGF.getc  #=> "f"
    ARGF.getc  #=> "o"
    ARGF.getc  #=> "o"
    ARGF.getc  #=> "\n"
    ARGF.getc  #=> nil
    ARGF.getc  #=> nil

    static VALUE
    argf_getc(VALUE argf)
    {
        VALUE ch;

      retry:
        if (!next_argv()) return Qnil;
        if (ARGF_GENERIC_INPUT_P()) {
            ch = forward_current(rb_intern("getc"), 0, 0);
        }
        else {
            ch = rb_io_getc(ARGF.current_file);
        }
        if (NIL_P(ch) && ARGF.next_p != -1) {
            argf_close(argf);
            ARGF.next_p = 1;
            goto retry;
        }

        return ch;
    }

gets(sep=$/ [, getline_args]) → string or nil click to toggle source
gets(limit [, getline_args]) → string or nil
gets(sep, limit [, getline_args]) → string or nil

Returns the next line from the current file in `ARGF`.

By default lines are assumed to be separated by `$/`; to use a different character as a separator, supply it as a `String` for the sep argument.

The optional limit argument specifies how many characters of each line to return. By default all characters are returned.

See `IO.readlines` for details about getline_args.

    static VALUE
    argf_gets(int argc, VALUE *argv, VALUE argf)
    {
        VALUE line;

        line = argf_getline(argc, argv, argf);
        rb_lastline_set(line);

        return line;
    }

inplace_mode → String click to toggle source

Returns the file extension appended to the names of backup copies of modified files under in-place edit mode. This value can be set using `ARGF.inplace_mode=` or passing the `-i` switch to the Ruby binary.

    static VALUE
    argf_inplace_mode_get(VALUE argf)
    {
        if (!ARGF.inplace) return Qnil;
        if (NIL_P(ARGF.inplace)) return rb_str_new(0, 0);
        return rb_str_dup(ARGF.inplace);
    }

inplace_mode = ext → ARGF click to toggle source

Sets the filename extension for in-place editing mode to the given `String`. The backup copy of each file being edited has this value appended to its filename.

For example:

    $ ruby argf.rb file.txt

    ARGF.inplace_mode = '.bak'
    ARGF.each_line do |line|
      print line.sub("foo","bar")
    end

First, file.txt.bak is created as a backup copy of file.txt. Then, each line of file.txt has the first occurrence of “foo” replaced with “bar”.

    static VALUE
    argf_inplace_mode_set(VALUE argf, VALUE val)
    {
        if (!RTEST(val)) {
            ARGF.inplace = Qfalse;
        }
        else if (StringValueCStr(val), !RSTRING_LEN(val)) {
            ARGF.inplace = Qnil;
        }
        else {
            ARGF.inplace = rb_str_new_frozen(val);
        }
        return argf;
    }

inspect()

Returns “ARGF”.

Alias for: to_s
internal_encoding → encoding click to toggle source

Returns the internal encoding for strings read from `ARGF` as an `Encoding` object.

If `ARGF.set_encoding` has been called with two encoding names, the second is returned. Otherwise, if `Encoding.default_external` has been set, that value is returned. Failing that, if a default external encoding was specified on the command-line, that value is used. If the encoding is unknown, `nil` is returned.

    static VALUE
    argf_internal_encoding(VALUE argf)
    {
        return argf_encoding(argf, rb_io_internal_encoding);
    }

lineno → integer click to toggle source

Returns the current line number of `ARGF` as a whole. This value can be set manually with `ARGF.lineno=`.

For example:

    ARGF.lineno   #=> 0
    ARGF.readline #=> "This is line 1\n"
    ARGF.lineno   #=> 1

    static VALUE
    argf_lineno(VALUE argf)
    {
        return INT2FIX(ARGF.lineno);
    }

lineno = integer → integer click to toggle source

Sets the line number of `ARGF` as a whole to the given `Integer`.

`ARGF` sets the line number automatically as you read data, so normally you will not need to set it explicitly. To access the current line number use `ARGF.lineno`.

For example:

    ARGF.lineno      #=> 0
    ARGF.readline    #=> "This is line 1\n"
    ARGF.lineno      #=> 1
    ARGF.lineno = 0  #=> 0
    ARGF.lineno      #=> 0

    static VALUE
    argf_set_lineno(VALUE argf, VALUE val)
    {
        ARGF.lineno = NUM2INT(val);
        ARGF.last_lineno = ARGF.lineno;
        return val;
    }

path → String

Returns the current filename. “-” is returned when the current file is STDIN.

For example:

    $ echo "foo" > foo
    $ echo "bar" > bar
    $ echo "glark" > glark

    $ ruby argf.rb foo bar glark

    ARGF.filename  #=> "foo"
    ARGF.read(5)   #=> "foo\nb"
    ARGF.filename  #=> "bar"
    ARGF.skip
    ARGF.filename  #=> "glark"

Alias for: filename
pos → Integer

Returns the current offset (in bytes) of the current file in `ARGF`.

    ARGF.pos    #=> 0
    ARGF.gets   #=> "This is line one\n"
    ARGF.pos    #=> 17

Alias for: tell
pos = position → Integer click to toggle source

Seeks to the position given by position (in bytes) in `ARGF`.

For example:

    ARGF.pos = 17
    ARGF.gets   #=> "This is line two\n"

    static VALUE
    argf_set_pos(VALUE argf, VALUE offset)
    {
        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream to set position");
        }
        ARGF_FORWARD(1, &offset);
        return rb_io_set_pos(ARGF.current_file, offset);
    }

print(*objects) → nil click to toggle source

Writes the given objects to the stream; returns `nil`. Appends the output record separator `$OUTPUT_RECORD_SEPARATOR` (`$\`), if it is not `nil`. See Line IO.

With argument `objects` given, for each object:

- Converts via its method `to_s` if not a string.

- Writes to the stream.

- If not the last object, writes the output field separator `$OUTPUT_FIELD_SEPARATOR` (`$,`) if it is not `nil`.

With default separators:

    f = File.open('t.tmp', 'w+')
    objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
    p $OUTPUT_RECORD_SEPARATOR
    p $OUTPUT_FIELD_SEPARATOR
    f.print(*objects)
    f.rewind
    p f.read
    f.close

Output:

    nil
    nil
    "00.00/10+0izerozero"

With specified separators:

    $\ = "\n"
    $, = ','
    f.rewind
    f.print(*objects)
    f.rewind
    p f.read

Output:

    "0,0.0,0/1,0+0i,zero,zero\n"

With no argument given, writes the content of `$_` (which is usually the most recent user input):

    f = File.open('t.tmp', 'w+')
    gets # Sets $_ to the most recent user input.
    f.print
    f.close

    VALUE
    rb_io_print(int argc, const VALUE *argv, VALUE out)
    {
        int i;
        VALUE line;

        /* if no argument given, print `$_' */
        if (argc == 0) {
            argc = 1;
            line = rb_lastline_get();
            argv = &line;
        }
        if (argc > 1 && !NIL_P(rb_output_fs)) {
            rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
        }
        for (i=0; i<argc; i++) {
            if (!NIL_P(rb_output_fs) && i>0) {
                rb_io_write(out, rb_output_fs);
            }
            rb_io_write(out, argv[i]);
        }
        if (argc > 0 && !NIL_P(rb_output_rs)) {
            rb_io_write(out, rb_output_rs);
        }

        return Qnil;
    }

printf(format_string, *objects) → nil click to toggle source

Formats and writes `objects` to the stream.

For details on `format_string`, see Format Specifications.

    VALUE
    rb_io_printf(int argc, const VALUE *argv, VALUE out)
    {
        rb_io_write(out, rb_f_sprintf(argc, argv));
        return Qnil;
    }

putc(object) → object click to toggle source

Writes a character to the stream. See Character IO.

If `object` is numeric, converts to integer if necessary, then writes the character whose code is the least significant byte; if `object` is a string, writes the first character:

    $stdout.putc "A"
    $stdout.putc 65

Output:

    AA

    static VALUE
    rb_io_putc(VALUE io, VALUE ch)
    {
        VALUE str;
        if (RB_TYPE_P(ch, T_STRING)) {
            str = rb_str_substr(ch, 0, 1);
        }
        else {
            char c = NUM2CHR(ch);
            str = rb_str_new(&c, 1);
        }
        rb_io_write(io, str);
        return ch;
    }

puts(*objects) → nil click to toggle source

Writes the given `objects` to the stream, which must be open for writing; returns `nil`.\ Writes a newline after each that does not already end with a newline sequence. If called without arguments, writes a newline. See Line IO.

Note that each added newline is the character `"\n"<//tt>, not the output record separator (<tt>$\`).

Treatment for each object:

- String: writes the string.

- Neither string nor array: writes `object.to_s`.

- Array: writes each element of the array; arrays may be nested.

To keep these examples brief, we define this helper method:

    def show(*objects)
      # Puts objects to file.
      f = File.new('t.tmp', 'w+')
      f.puts(objects)
      # Return file content.
      f.rewind
      p f.read
      f.close
    end

    # Strings without newlines.
    show('foo', 'bar', 'baz')     # => "foo\nbar\nbaz\n"
    # Strings, some with newlines.
    show("foo\n", 'bar', "baz\n") # => "foo\nbar\nbaz\n"

    # Neither strings nor arrays:
    show(0, 0.0, Rational(0, 1), Complex(9, 0), :zero)
    # => "0\n0.0\n0/1\n9+0i\nzero\n"

    # Array of strings.
    show(['foo', "bar\n", 'baz']) # => "foo\nbar\nbaz\n"
    # Nested arrays.
    show([[[0, 1], 2, 3], 4, 5])  # => "0\n1\n2\n3\n4\n5\n"

    VALUE
    rb_io_puts(int argc, const VALUE *argv, VALUE out)
    {
        VALUE line, args[2];

        /* if no argument given, print newline. */
        if (argc == 0) {
            rb_io_write(out, rb_default_rs);
            return Qnil;
        }
        for (int i = 0; i < argc; i++) {
            // Convert the argument to a string:
            if (RB_TYPE_P(argv[i], T_STRING)) {
                line = argv[i];
            }
            else if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
                continue;
            }
            else {
                line = rb_obj_as_string(argv[i]);
            }

            // Write the line:
            int n = 0;
            if (RSTRING_LEN(line) == 0) {
                args[n++] = rb_default_rs;
            }
            else {
                args[n++] = line;
                if (!rb_str_end_with_asciichar(line, '\n')) {
                    args[n++] = rb_default_rs;
                }
            }

            rb_io_writev(out, n, args);
        }

        return Qnil;
    }

read([length [, outbuf]]) → string, outbuf, or nil click to toggle source

Reads length bytes from `ARGF`. The files named on the command line are concatenated and treated as a single file by this method, so when called without arguments the contents of this pseudo file are returned in their entirety.

length must be a non-negative integer or `nil`.

If length is a positive integer, `read` tries to read length bytes without any conversion (binary mode). It returns `nil` if an EOF is encountered before anything can be read. Fewer than length bytes are returned if an EOF is encountered during the read. In the case of an integer length, the resulting string is always in ASCII-8BIT encoding.

If length is omitted or is `nil`, it reads until EOF and the encoding conversion is applied, if applicable. A string is returned even if EOF is encountered before any data is read.

If length is zero, it returns an empty string (`""`).

If the optional outbuf argument is present, it must reference a `String`, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

For example:

    $ echo "small" > small.txt
    $ echo "large" > large.txt
    $ ./glark.rb small.txt large.txt

    ARGF.read      #=> "small\nlarge"
    ARGF.read(200) #=> "small\nlarge"
    ARGF.read(2)   #=> "sm"
    ARGF.read(0)   #=> ""

Note that this method behaves like the fread() function in C. This means it retries to invoke read(2) system calls to read data with the specified length. If you need the behavior like a single read(2) system call, consider `ARGF#readpartial` or `ARGF#read_nonblock`.

    static VALUE
    argf_read(int argc, VALUE *argv, VALUE argf)
    {
        VALUE tmp, str, length;
        long len = 0;

        rb_scan_args(argc, argv, "02", &length, &str);
        if (!NIL_P(length)) {
            len = NUM2LONG(argv[0]);
        }
        if (!NIL_P(str)) {
            StringValue(str);
            rb_str_resize(str,0);
            argv[1] = Qnil;
        }

      retry:
        if (!next_argv()) {
            return str;
        }
        if (ARGF_GENERIC_INPUT_P()) {
            tmp = argf_forward(argc, argv, argf);
        }
        else {
            tmp = io_read(argc, argv, ARGF.current_file);
        }
        if (NIL_P(str)) str = tmp;
        else if (!NIL_P(tmp)) rb_str_append(str, tmp);
        if (NIL_P(tmp) || NIL_P(length)) {
            if (ARGF.next_p != -1) {
                argf_close(argf);
                ARGF.next_p = 1;
                goto retry;
            }
        }
        else if (argc >= 1) {
            long slen = RSTRING_LEN(str);
            if (slen < len) {
                argv[0] = LONG2NUM(len - slen);
                goto retry;
            }
        }
        return str;
    }

read_nonblock(maxlen[, options]) → string click to toggle source
read_nonblock(maxlen, outbuf[, options]) → outbuf

Reads at most maxlen bytes from the `ARGF` stream in non-blocking mode.

    static VALUE
    argf_read_nonblock(int argc, VALUE *argv, VALUE argf)
    {
        VALUE opts;

        rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);

        if (!NIL_P(opts))
            argc--;

        return argf_getpartial(argc, argv, argf, opts, 1);
    }

readbyte → Integer click to toggle source

Reads the next 8-bit byte from `ARGF` and returns it as an `Integer`. Raises an `EOFError` after the last byte of the last file has been read.

For example:

    $ echo "foo" > file
    $ ruby argf.rb file

    ARGF.readbyte  #=> 102
    ARGF.readbyte  #=> 111
    ARGF.readbyte  #=> 111
    ARGF.readbyte  #=> 10
    ARGF.readbyte  #=> end of file reached (EOFError)

    static VALUE
    argf_readbyte(VALUE argf)
    {
        VALUE c;

        NEXT_ARGF_FORWARD(0, 0);
        c = argf_getbyte(argf);
        if (NIL_P(c)) {
            rb_eof_error();
        }
        return c;
    }

readchar → String or nil click to toggle source

Reads the next character from `ARGF` and returns it as a `String`. Raises an `EOFError` after the last character of the last file has been read.

For example:

    $ echo "foo" > file
    $ ruby argf.rb file

    ARGF.readchar  #=> "f"
    ARGF.readchar  #=> "o"
    ARGF.readchar  #=> "o"
    ARGF.readchar  #=> "\n"
    ARGF.readchar  #=> end of file reached (EOFError)

    static VALUE
    argf_readchar(VALUE argf)
    {
        VALUE ch;

      retry:
        if (!next_argv()) rb_eof_error();
        if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
            ch = forward_current(rb_intern("getc"), 0, 0);
        }
        else {
            ch = rb_io_getc(ARGF.current_file);
        }
        if (NIL_P(ch) && ARGF.next_p != -1) {
            argf_close(argf);
            ARGF.next_p = 1;
            goto retry;
        }

        return ch;
    }

readline(sep=$/) → string click to toggle source
readline(limit) → string
readline(sep, limit) → string

Returns the next line from the current file in `ARGF`.

By default lines are assumed to be separated by `$/`; to use a different character as a separator, supply it as a `String` for the sep argument.

The optional limit argument specifies how many characters of each line to return. By default all characters are returned.

An `EOFError` is raised at the end of the file.

    static VALUE
    argf_readline(int argc, VALUE *argv, VALUE argf)
    {
        VALUE line;

        if (!next_argv()) rb_eof_error();
        ARGF_FORWARD(argc, argv);
        line = argf_gets(argc, argv, argf);
        if (NIL_P(line)) {
            rb_eof_error();
        }

        return line;
    }

readlines(sep = $/, chomp: false) → array click to toggle source
readlines(limit, chomp: false) → array
readlines(sep, limit, chomp: false) → array

Reads each file in `ARGF` in its entirety, returning an `Array` containing lines from the files. Lines are assumed to be separated by sep.

    lines = ARGF.readlines
    lines[0]                #=> "This is line one\n"

See `IO.readlines` for a full description of all options.

    static VALUE
    argf_readlines(int argc, VALUE *argv, VALUE argf)
    {
        long lineno = ARGF.lineno;
        VALUE lines, ary;

        ary = rb_ary_new();
        while (next_argv()) {
            if (ARGF_GENERIC_INPUT_P()) {
                lines = forward_current(rb_intern("readlines"), argc, argv);
            }
            else {
                lines = rb_io_readlines(argc, argv, ARGF.current_file);
                argf_close(argf);
            }
            ARGF.next_p = 1;
            rb_ary_concat(ary, lines);
            ARGF.lineno = lineno + RARRAY_LEN(ary);
            ARGF.last_lineno = ARGF.lineno;
        }
        ARGF.init_p = 0;
        return ary;
    }

Also aliased as: to_a
readpartial(maxlen) → string click to toggle source
readpartial(maxlen, outbuf) → outbuf

Reads at most maxlen bytes from the `ARGF` stream.

If the optional outbuf argument is present, it must reference a `String`, which will receive the data. The outbuf will contain only the received data after the method call even if it is not empty at the beginning.

It raises `EOFError` on end of `ARGF` stream. Since `ARGF` stream is a concatenation of multiple files, internally EOF is occur for each file. `ARGF.readpartial` returns empty strings for EOFs except the last one and raises `EOFError` for the last one.

    static VALUE
    argf_readpartial(int argc, VALUE *argv, VALUE argf)
    {
        return argf_getpartial(argc, argv, argf, Qnil, 0);
    }

rewind → 0 click to toggle source

Positions the current file to the beginning of input, resetting `ARGF.lineno` to zero.

    ARGF.readline   #=> "This is line one\n"
    ARGF.rewind     #=> 0
    ARGF.lineno     #=> 0
    ARGF.readline   #=> "This is line one\n"

    static VALUE
    argf_rewind(VALUE argf)
    {
        VALUE ret;
        int old_lineno;

        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream to rewind");
        }
        ARGF_FORWARD(0, 0);
        old_lineno = RFILE(ARGF.current_file)->fptr->lineno;
        ret = rb_io_rewind(ARGF.current_file);
        if (!global_argf_p(argf)) {
            ARGF.last_lineno = ARGF.lineno -= old_lineno;
        }
        return ret;
    }

seek(amount, whence=IO::SEEK_SET) → 0 click to toggle source

Seeks to offset amount (an `Integer`) in the `ARGF` stream according to the value of whence. See `IO#seek` for further details.

    static VALUE
    argf_seek_m(int argc, VALUE *argv, VALUE argf)
    {
        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream to seek");
        }
        ARGF_FORWARD(argc, argv);
        return rb_io_seek_m(argc, argv, ARGF.current_file);
    }

set_encoding(ext_enc) → ARGF click to toggle source
set_encoding("ext_enc:int_enc") → ARGF
set_encoding(ext_enc, int_enc) → ARGF
set_encoding("ext_enc:int_enc", opt) → ARGF
set_encoding(ext_enc, int_enc, opt) → ARGF

If single argument is specified, strings read from `ARGF` are tagged with the encoding specified.

If two encoding names separated by a colon are given, e.g. “ascii:utf-8”, the read string is converted from the first encoding (external encoding) to the second encoding (internal encoding), then tagged with the second encoding.

If two arguments are specified, they must be encoding objects or encoding names. Again, the first specifies the external encoding; the second specifies the internal encoding.

If the external encoding and the internal encoding are specified, the optional `Hash` argument can be used to adjust the conversion process. The structure of this hash is explained in the `String#encode` documentation.

For example:

    ARGF.set_encoding('ascii')         # Tag the input as US-ASCII text
    ARGF.set_encoding(Encoding::UTF_8) # Tag the input as UTF-8 text
    ARGF.set_encoding('utf-8','ascii') # Transcode the input from US-ASCII
                                       # to UTF-8.

    static VALUE
    argf_set_encoding(int argc, VALUE *argv, VALUE argf)
    {
        rb_io_t *fptr;

        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream to set encoding");
        }
        rb_io_set_encoding(argc, argv, ARGF.current_file);
        GetOpenFile(ARGF.current_file, fptr);
        ARGF.encs = fptr->encs;
        return argf;
    }

skip → ARGF click to toggle source

Sets the current file to the next file in ARGV. If there aren’t any more files it has no effect.

For example:

    $ ruby argf.rb foo bar
    ARGF.filename  #=> "foo"
    ARGF.skip
    ARGF.filename  #=> "bar"

    static VALUE
    argf_skip(VALUE argf)
    {
        if (ARGF.init_p && ARGF.next_p == 0) {
            argf_close(argf);
            ARGF.next_p = 1;
        }
        return argf;
    }

tell → Integer click to toggle source

Returns the current offset (in bytes) of the current file in `ARGF`.

    ARGF.pos    #=> 0
    ARGF.gets   #=> "This is line one\n"
    ARGF.pos    #=> 17

    static VALUE
    argf_tell(VALUE argf)
    {
        if (!next_argv()) {
            rb_raise(rb_eArgError, "no stream to tell");
        }
        ARGF_FORWARD(0, 0);
        return rb_io_tell(ARGF.current_file);
    }

Also aliased as: pos
to_a(sep = $/, chomp: false) → array
to_a(limit, chomp: false) → array
to_a(sep, limit, chomp: false) → array

Reads each file in `ARGF` in its entirety, returning an `Array` containing lines from the files. Lines are assumed to be separated by sep.

    lines = ARGF.readlines
    lines[0]                #=> "This is line one\n"

See `IO.readlines` for a full description of all options.

Alias for: readlines
to_i → integer

Returns an integer representing the numeric file descriptor for the current file. Raises an `ArgumentError` if there isn’t a current file.

    ARGF.fileno    #=> 3

Alias for: fileno
to_io → IO click to toggle source

Returns an `IO` object representing the current file. This will be a `File` object unless the current file is a stream such as STDIN.

For example:

    ARGF.to_io    #=> #<File:glark.txt>
    ARGF.to_io    #=> #<IO:<STDIN>>

    static VALUE
    argf_to_io(VALUE argf)
    {
        next_argv();
        ARGF_FORWARD(0, 0);
        return ARGF.current_file;
    }

to_s → String click to toggle source

Returns “ARGF”.

    static VALUE
    argf_to_s(VALUE argf)
    {
        return rb_str_new2("ARGF");
    }

Also aliased as: inspect
to_write_io → io click to toggle source

Returns `IO` instance tied to ARGF for writing if inplace mode is enabled.

    static VALUE
    argf_write_io(VALUE argf)
    {
        if (!RTEST(ARGF.current_file)) {
            rb_raise(rb_eIOError, "not opened for writing");
        }
        return GetWriteIO(ARGF.current_file);
    }

write(*objects) → integer click to toggle source

Writes each of the given `objects` if inplace mode.

    static VALUE
    argf_write(int argc, VALUE *argv, VALUE argf)
    {
        return rb_io_writev(argf_write_io(argf), argc, argv);
    }