Spec-Zone.ru › Ruby 3.4

class ARGF

Parent:
Object
Included modules:
Enumerable

ARGF и ARGV

Объект ARGF работает с массивом в глобальной переменной ARGV для того, чтобы сделать потоки $stdin и файловые потоки доступными в программе Ruby:

  • ARGV можно рассматривать как массив вектора аргументов.

    Изначально он содержит аргументы и параметры командной строки, передаваемые в программу Ruby; программа может изменять этот массив по своему усмотрению.

  • ARGF можно рассматривать как объект файлов аргументов.

    Он может обращаться к файловым потокам и/или потоку $stdin, основываясь на том, что он находит в ARGV. Это удобный способ для командной строки указать потоки для чтения программой Ruby.

Чтение

ARGF может читать из потоков источника, которые в любой конкретный момент определяются содержимым ARGV.

Простейший случай

Когда первое чтение ARGF происходит с пустым ARGV ([]), источником является $stdin:

  • Файл t.rb:

    p ['ARGV', ARGV]
    p ['ARGF.read', ARGF.read]
    
  • Команды и выводы (см. содержимое файлов foo.txt и 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"]

О примерах

Многие примеры здесь предполагают существование файлов foo.txt и bar.txt:

$ cat foo.txt
Foo 0
Foo 1
$ cat bar.txt
Bar 0
Bar 1
Bar 2
Bar 3

Источники в ARGV

Для любого чтения ARGF кроме простейшего случая (то есть кроме первого чтения ARGF с пустым ARGV), источники находятся в ARGV.

ARGF предполагает, что каждый элемент в массиве ARGV является потенциальным источником и представляет собой:

  • Путь к строке файла, который может быть открыт как поток.

  • Символ '-', означающий поток $stdin.

Каждый элемент, который не является одним из этих, должен быть удалён из ARGV перед тем, как ARGF обращается к этому источнику.

В следующем примере:

  • Пути к файлам foo.txt и bar.txt могут быть сохранены в качестве потенциальных источников.

  • Параметры --xyzzy и --mojo должны быть удалены.

Пример:

  • Файл t.rb:

    # Print arguments (and options, if any) found on command line.
    p ['ARGV', ARGV]
    
  • Команда и вывод:

    $ ruby t.rb --xyzzy --mojo foo.txt bar.txt
    ["ARGV", ["--xyzzy", "--mojo", "foo.txt", "bar.txt"]]

Доступ ARGF к потокам учитывает элементы ARGV, слева направо:

  • Файл t.rb:

    p "ARGV: #{ARGV}"
    p "Line: #{ARGF.read}" # Read everything from all specified streams.
    
  • Команда и вывод:

    $ 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 — обычный массив, вы можете манипулировать им, чтобы управлять тем, какие источники учитывает ARGF:

  • Если вы удалите элемент из ARGV, ARGF не будет учитывать соответствующий источник.

  • Если вы добавите элемент в ARGV, ARGF будет учитывать соответствующий источник.

Каждый элемент в ARGV удаляется при обращении к соответствующему источнику; когда все источники обработаны, массив пустой:

  • Файл t.rb:

    until ARGV.empty? && ARGF.eof?
      p "ARGV: #{ARGV}"
      p "Line: #{ARGF.readline}" # Read each line from each specified stream.
    end
    
  • Команда и вывод:

    $ 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

Массив ARGV может содержать пути к файлам, которые определяют источники для чтения ARGF.

Эта программа выводит то, что она читает из файлов по указанным в командной строке путям:

  • Файл t.rb:

    p ['ARGV', ARGV]
    # Read and print all content from the specified sources.
    p ['ARGF.read', ARGF.read]
    
  • Команда и вывод:

    $ 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 в ARGV

Чтобы указать поток $stdin в ARGV, используйте символ '-':

  • Файл t.rb:

    p ['ARGV', ARGV]
    p ['ARGF.read', ARGF.read]
    
  • Команда и вывод:

    $ echo "Open the pod bay doors, Hal." | ruby t.rb -
    ["ARGV", ["-"]]
    ["ARGF.read", "Open the pod bay doors, Hal.\n"]

Когда символ '-' не задан, поток $stdin игнорируется (исключение: см. Указание $stdin в ARGV):

  • Команда и вывод:

    $ 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

Для читателя ARGF, ARGV может содержать любые смеси путей к файлам и символа '-', включая повторения.

Модификации массива ARGV

Выполняющаяся программа Ruby может вносить любые изменения в массив ARGV; текущее значение ARGV влияет на чтение ARGF.

Пустой ARGV

Для пустого ARGV, метод чтения ARGF либо возвращает nil, либо вызывает исключение, в зависимости от конкретного метода.

Другие методы чтения

Как видно выше, метод ARGF#read считывает содержимое всех источников в одну строку. Другие методы ARGF предоставляют другие способы доступа к этому содержимому; они включают:

  • Доступ к байтам: each_byte, getbyte, readbyte.

  • Доступ к символам: each_char, getc, readchar.

  • Доступ к кодовым точкам: each_codepoint.

  • Доступ к строкам: each_line, gets, readline, readlines.

  • Доступ к источнику: read, read_nonblock, readpartial.

О модуле Enumerable

ARGF включает модуль Enumerable. Практически все методы в Enumerable вызывают метод each в включающем классе.

Обратите внимание: В ARGF метод each возвращает данные из источников, а не из ARGV; поэтому, например, ARGF#entries возвращает массив строк из источников, а не массив строк из ARGV:

  • Файл t.rb:

    p ['ARGV', ARGV]
    p ['ARGF.entries', ARGF.entries]
    
  • Команда и вывод:

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

Запись

Если режим работы на месте включён, ARGF может записывать в целевые потоки, которые в любой конкретный момент определяются содержимым ARGV.

Методы, относящиеся к режиму работы на месте:

  • inplace_mode

  • inplace_mode=

  • to_write_io

Методы для записи:

  • print

  • printf

  • putc

  • puts

  • write

Методы открытого экземпляра

argv → ARGV
Исходный код
static VALUE
argf_argv(VALUE argf)
{
    return ARGF.argv;
}

Возвращает массив ARGV, содержащий аргументы, переданные вашей скрипту, по одному на элемент.

Например:

$ ruby argf.rb -v glark.txt

ARGF.argv   #=> ["-v", "glark.txt"]
binmode → ARGF
Исходный код
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;
}

Переводит ARGF в двоичный режим. После перевода потока в двоичный режим, его нельзя переключить обратно в текстовый. Этот параметр имеет следующие эффекты:

  • Преобразование символов новой строки отключено.

  • Encoding преобразование отключено.

  • Содержание обрабатывается как ASCII-8BIT.

binmode? → true или false
Исходный код
static VALUE
argf_binmode_p(VALUE argf)
{
    return RBOOL(ARGF.binmode);
}

Возвращает true, если ARGF считывается в двоичном режиме; в противном случае — false. Для включения двоичного режима используйте ARGF.binmode.

Например:

ARGF.binmode?  #=> false
ARGF.binmode
ARGF.binmode?  #=> true
close → ARGF
Исходный код
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;
}

Закрывает текущий файл и переходит к следующему файлу в ARGV. Если больше файлов для открытия нет, просто закрывает текущий файл. STDIN не будет закрыт.

Например:

$ ruby argf.rb foo bar

ARGF.filename  #=> "foo"
ARGF.close
ARGF.filename  #=> "bar"
ARGF.close
closed? → true или false
Исходный код
static VALUE
argf_closed(VALUE argf)
{
    next_argv();
    ARGF_FORWARD(0, 0);
    return rb_io_closed_p(ARGF.current_file);
}

Возвращает true, если текущий файл закрыт; в противном случае — false. Для фактического закрытия текущего файла используйте ARGF.close.

each(sep=$/) {|line| block } → ARGF
each(sep=$/, limit) {|line| block } → ARGF
each(...) → an_enumerator
Исходный код
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;
}

Возвращает перечислитель, который итерируется по каждой строке (разделенной sep, по умолчанию символ новой строки вашей платформы) каждого файла в ARGV. Если предоставлен блок, каждая строка поочередно передаётся в блок; в противном случае возвращается перечислитель. Необязательный аргумент limit — целое число, определяющее максимальную длину каждой строки; более длинные строки будут разбиваться в соответствии с этим ограничением.

Этот метод позволяет рассматривать файлы, переданные в командной строке, как один файл, состоящий из конкатенации каждого указанного файла. После возврата последней строки первого файла возвращается первая строка второго файла. Методы ARGF.filename и ARGF.lineno можно использовать для определения имени файла текущей строки и номера строки всего ввода, соответственно.

Например, следующий код выводит каждую строку каждого имени файла с префиксом номера строки, отображая имя файла один раз на файл:

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

В то время как следующий код выводит сначала только имя первого файла, а затем содержимое с номером строки, подсчитанным через все указанные файлы.

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.lineno == 1
  puts "#{ARGF.lineno}: #{line}"
end
Также переименовано в: each_line
each_byte {|byte| block } → ARGF
each_byte → an_enumerator
Исходный код
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;
}

Итерируется по каждому байту каждого файла в ARGV. Байты возвращаются как целые числа Integer в диапазоне от 0 до 255.

Этот метод позволяет обрабатывать файлы, переданные в командной строке, как один файл, состоящий из конкатенации каждого указанного файла. После возврата последнего байта первого файла возвращается первый байт второго файла. Метод ARGF.filename можно использовать для определения имени файла текущего байта.

Если блок не задан, возвращается перечислитель.

Например:

ARGF.bytes.to_a  #=> [35, 32, ... 95, 10]
each_char {|char| block } → ARGF
each_char → an_enumerator
Исходный код
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;
}

Итерируется по каждому символу каждого файла в ARGF.

Этот метод позволяет обрабатывать файлы, переданные в командной строке, как один файл, состоящий из конкатенации каждого указанного файла. После возврата последнего символа первого файла возвращается первый символ второго файла. Метод ARGF.filename можно использовать для определения имени файла, в котором находится текущий символ.

Если блок не задан, возвращается перечислитель.

each_codepoint {|codepoint| block } → ARGF
each_codepoint → an_enumerator
Исходный код
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;
}

Итерируется по каждому кодовому пункту каждого файла в ARGF.

Этот метод позволяет обрабатывать файлы, переданные в командной строке, как один файл, состоящий из конкатенации каждого указанного файла. После возврата последнего кодового пункта первого файла возвращается первый кодовый пункт второго файла. Метод ARGF.filename можно использовать для определения имени файла, в котором находится текущий кодовый пункт.

Если блок не задан, возвращается перечислитель.

each_line(sep=$/) {|line| блок } → ARGF
each_line(sep=$/, limit) {|line| блок } → ARGF
each_line(...) → перечислитель

Возвращает перечислитель, который итерируется по каждой строке (разделенной sep, по умолчанию — символом новой строки вашей платформы) каждого файла в ARGV. Если задан блок, каждая строка по очереди передается в блок; в противном случае возвращается перечислитель. Необязательный аргумент limit — целое число, определяющее максимальную длину каждой строки; более длинные строки будут разделены в соответствии с этим лимитом.

Этот метод позволяет обработать файлы, заданные в командной строке, как единый файл, состоящий из конкатенации каждого указанного файла. После возвращения последней строки первого файла возвращается первая строка второго файла. Методы ARGF.filename и ARGF.lineno могут использоваться для определения имени текущего файла и номера строки всего ввода соответственно.

Например, следующий код выводит каждую строку каждого указанного файла, предварительно указав её номер, отображая имя файла один раз на файл:

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

В то время как следующий код сначала отображает только имя первого файла, а затем содержимое со счётом строк по всем указанным файлам.

ARGF.each_line do |line|
  puts ARGF.filename if ARGF.lineno == 1
  puts "#{ARGF.lineno}: #{line}"
end
Псевдоним для: each
eof → true или false
Исходный код
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;
}

Возвращает true, если текущий файл в ARGF находится в конце файла, т. е. не имеет данных для чтения. Поток должен быть открыт для чтения, иначе будет вызвано исключение IOError.

$ echo "eof" | ruby argf.rb

ARGF.eof?                 #=> false
3.times { ARGF.readchar }
ARGF.eof?                 #=> false
ARGF.readchar             #=> "\n"
ARGF.eof?                 #=> true
Также алиас для: eof?
eof? → true или false

Возвращает true, если текущий файл в ARGF находится в конце файла, т. е. не имеет данных для чтения. Поток должен быть открыт для чтения, иначе будет вызвано исключение IOError.

$ echo "eof" | ruby argf.rb

ARGF.eof?                 #=> false
3.times { ARGF.readchar }
ARGF.eof?                 #=> false
ARGF.readchar             #=> "\n"
ARGF.eof?                 #=> true
Псевдоним для: eof
external_encoding → кодировка
Исходный код
static VALUE
argf_external_encoding(VALUE argf)
{
    return argf_encoding(argf, rb_io_external_encoding);
}

Возвращает внешнюю кодировку для файлов, считанных из ARGF, как объект Encoding. Внешняя кодировка — это кодировка текста, хранящегося в файле. Противопоставьте этому ARGF.internal_encoding, которая является кодировкой, используемой для представления этого текста внутри Ruby.

Для установки внешней кодировки используйте ARGF.set_encoding.

Например:

ARGF.external_encoding  #=>  #<Encoding:UTF-8>
file → объект IO или File
Исходный код
static VALUE
argf_file(VALUE argf)
{
    next_argv();
    return ARGF.current_file;
}

Возвращает текущий файл как объект IO или File. $stdin возвращается, когда текущий файл — STDIN.

Например:

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

$ ruby argf.rb foo bar

ARGF.file      #=> #<File:foo>
ARGF.read(5)   #=> "foo\nb"
ARGF.file      #=> #<File:bar>
filename → Строка
Исходный код
static VALUE
argf_filename(VALUE argf)
{
    next_argv();
    return ARGF.filename;
}

Возвращает текущее имя файла. «-» возвращается, когда текущий файл — STDIN.

Например:

$ 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"
Также алиас для: path
fileno → целое число
Исходный код
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);
}

Возвращает целое число, представляющее числовой дескриптор файла для текущего файла. Вызывает исключение ArgumentError, если текущего файла нет.

ARGF.fileno    #=> 3
Также алиас для: to_i
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;
}

Получает следующий 8-битный байт (0..255) из ARGF. Возвращает nil при вызове в конце потока.

Например:

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

ARGF.getbyte #=> 102
ARGF.getbyte #=> 111
ARGF.getbyte #=> 111
ARGF.getbyte #=> 10
ARGF.getbyte #=> nil
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;
}

Читает следующий символ из ARGF и возвращает его как String. Возвращает nil в конце потока.

ARGF обрабатывает файлы, указанные в командной строке, как единый файл, созданный путём конкатенации их содержимого. После возвращения последнего символа первого файла он возвращает первый символ второго файла и так далее.

Например:

$ 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
gets(sep=$/ [, getline_args]) → строка или nil
gets(limit [, getline_args]) → строка или nil
gets(sep, limit [, getline_args]) → строка или nil
Исходный код
static VALUE
argf_gets(int argc, VALUE *argv, VALUE argf)
{
    VALUE line;

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

    return line;
}

Возвращает следующую строку из текущего файла в ARGF.

По умолчанию строки предполагаются разделёнными $/; для использования другого символа в качестве разделителя, передайте его как String для аргумента sep.

Необязательный аргумент limit указывает, сколько символов каждой строки возвращать. По умолчанию возвращаются все символы.

См. IO.readlines для получения подробностей о getline_args.

inplace_mode → Строка
Исходный код
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);
}

Возвращает расширение файла, добавляемое к именам резервных копий изменённых файлов в режиме редактирования на месте. Это значение можно установить, используя ARGF.inplace_mode= или передав переключатель -i в двоичный файл Ruby.

inplace_mode = ext → ARGF
Исходный код
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;
}

Устанавливает расширение файла для режима редактирования на месте заданному String. Копия резервной копии каждого редактируемого файла имеет это значение, добавленное к имени файла.

Например:

$ ruby argf.rb file.txt

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

Сначала создается file.txt.bak как резервная копия file.txt. Затем каждая строка file.txt заменяет первое вхождение «foo» на «bar».

inspect
Псевдоним для: to_s
internal_encoding → encoding
Исходный код
static VALUE
argf_internal_encoding(VALUE argf)
{
    return argf_encoding(argf, rb_io_internal_encoding);
}

Возвращает кодировку, используемую для строк, считанных из ARGF, как объект Encoding.

Если ARGF.set_encoding был вызван с двумя именами кодировок, возвращается второе. В противном случае, если Encoding.default_external был установлен, возвращается это значение. В противном случае, если на командной строке была указана кодировка по умолчанию, используется это значение. Если кодировка неизвестна, возвращается nil.

lineno → целое
Исходный код
static VALUE
argf_lineno(VALUE argf)
{
    return INT2FIX(ARGF.lineno);
}

Возвращает текущий номер строки ARGF в целом. Это значение можно установить вручную с помощью ARGF.lineno=.

Например:

ARGF.lineno   #=> 0
ARGF.readline #=> "This is line 1\n"
ARGF.lineno   #=> 1
lineno = целое → целое
Исходный код
static VALUE
argf_set_lineno(VALUE argf, VALUE val)
{
    ARGF.lineno = NUM2INT(val);
    ARGF.last_lineno = ARGF.lineno;
    return val;
}

Устанавливает номер строки ARGF в целом на заданное Integer.

ARGF автоматически устанавливает номер строки при чтении данных, поэтому обычно нет необходимости устанавливать его явно. Чтобы получить текущий номер строки, используйте ARGF.lineno.

Например:

ARGF.lineno      #=> 0
ARGF.readline    #=> "This is line 1\n"
ARGF.lineno      #=> 1
ARGF.lineno = 0  #=> 0
ARGF.lineno      #=> 0
path → Строка

Возвращает текущее имя файла. «-» возвращается, когда текущий файл — STDIN.

Например:

$ 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"
Псевдоним для: filename
pos → Целое

Возвращает текущий смещение (в байтах) текущего файла в ARGF.

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17
Псевдоним для: tell
pos = position → Целое
Исходный код
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);
}

Перемещает указатель на позицию, заданную position (в байтах) в ARGF.

Например:

ARGF.pos = 17
ARGF.gets   #=> "This is line two\n"
print(*objects) → nil
Исходный код
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;
}

Записывает заданные объекты в поток; возвращает nil. Добавляет разделитель записей вывода $OUTPUT_RECORD_SEPARATOR ($\), если он не nil. См. Линейный ввод/вывод.

С аргументом objects для каждого объекта:

  • Преобразует с помощью метода to_s, если это не строка.

  • Записывает в поток.

  • Если это не последний объект, записывает разделитель полей вывода $OUTPUT_FIELD_SEPARATOR ($,), если он не nil.

С разделителями по умолчанию:

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

Вывод:

nil
nil
"00.00/10+0izerozero"

Со специфицированными разделителями:

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

Вывод:

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

Без аргументов записывает содержимое $_ (обычно последнее введенное пользователем значение):

f = File.open('t.tmp', 'w+')
gets # Sets $_ to the most recent user input.
f.print
f.close
printf(format_string, *objects) → nil
Исходный код
VALUE
rb_io_printf(int argc, const VALUE *argv, VALUE out)
{
    rb_io_write(out, rb_f_sprintf(argc, argv));
    return Qnil;
}

Форматирует и записывает objects в поток.

Для деталей по format_string, см. Спецификации форматирования.

putc(object) → object
Исходный код
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;
}

Записывает символ в поток. См. Символьный ввод/вывод.

Если object числовое, преобразует в целое, если необходимо, затем записывает символ, код которого — наименее значимый байт; если object строка, записывает первый символ:

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

Вывод:

AA
puts(*objects) → nil
Исходный код
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;
}

Записывает указанные objects в поток, который должен быть открыт для записи; возвращает nil. Записывает перевод строки после каждого, который не заканчивается последовательностью перевода строки. Если вызывается без аргументов, записывает перевод строки. См. Линейный ввод/вывод.

Обратите внимание, что каждая добавленная перевод строки — это символ "\n"<//tt>, not the output record separator (<tt>$\.

Обработка каждого объекта:

  • Строка: записывает строку.

  • Не строка и не массив: записывает object.to_s.

  • Массив: записывает каждый элемент массива; массивы могут быть вложенными.

Чтобы эти примеры были короче, мы определим этот вспомогательный метод:

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"
read([length [, outbuf]]) → строка, outbuf или nil
Исходный код
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;
}

Читает length байт из ARGF. Файлы, указанные в командной строке, конкатенируются и обрабатываются этим методом как один файл, поэтому при вызове без аргументов содержимое этого псевдофайла возвращается целиком.

length должен быть неотрицательным целым числом или nil.

Если length — положительное целое число, read пытается прочитать length байт без преобразования (в двоичном режиме). Он возвращает nil, если встречается конец файла (EOF) до того, как что-либо можно прочитать. Возвращается меньше, чем length байт, если во время чтения встречается конец файла (EOF). В случае целого числа length возвращаемая строка всегда имеет кодировку ASCII-8BIT.

Если length опущен или равен nil, он читает до конца файла (EOF) и применяет преобразование кодировки, если применимо. Строка возвращается даже если конец файла (EOF) встречен до чтения каких-либо данных.

Если length равен нулю, возвращается пустая строка ("").

Если присутствует необязательный аргумент outbuf, он должен ссылаться на String, который получит данные. outbuf будет содержать только полученные данные после вызова метода, даже если он не был пустым в начале.

Например:

$ 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)   #=> ""

Обратите внимание, что этот метод ведет себя как функция fread() в C. Это означает, что он повторно пытается вызвать системные вызовы read(2) для чтения данных с указанной длиной. Если вам нужен результат одного системного вызова read(2), рассмотрите ARGF#readpartial или ARGF#read_nonblock.

read_nonblock(maxlen[, options]) → строка
read_nonblock(maxlen, outbuf[, options]) → outbuf
Исходный код
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);
}

Читает не более maxlen байтов из потока ARGF в режиме без блокировки.

readbyte → Целое число
Исходный код
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;
}

Читает следующий байт размером 8 бит из ARGF и возвращает его как Integer. Поднимает EOFError после чтения последнего байта последнего файла.

Например:

$ 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)
readchar → Строка или nil
Исходный код
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;
}

Читает следующий символ из ARGF и возвращает его как String. Поднимает EOFError после чтения последнего символа последнего файла.

Например:

$ 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)
readline(sep=$/) → строка
readline(limit) → строка
readline(sep, limit) → строка
Исходный код
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;
}

Возвращает следующую строку из текущего файла в ARGF.

По умолчанию строки предполагаются разделенными $/; для использования другого символа в качестве разделителя, передайте его как String для аргумента sep.

Необязательный аргумент limit задает, сколько символов каждой строки вернуть. По умолчанию возвращаются все символы.

При достижении конца файла (EOF) возбуждается EOFError.

readlines(sep = $/, chomp: false) → массив
readlines(limit, chomp: false) → массив
readlines(sep, limit, chomp: false) → массив
Исходный код
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;
}

Читает каждый файл в ARGF полностью, возвращая Array содержащий строки из файлов. Строки предполагаются разделенными символом sep.

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

См. IO.readlines для полного описания всех параметров.

Также алиас: to_a
readpartial(maxlen) → строка
readpartial(maxlen, outbuf) → outbuf
Исходный код
static VALUE
argf_readpartial(int argc, VALUE *argv, VALUE argf)
{
    return argf_getpartial(argc, argv, argf, Qnil, 0);
}

Читает не более maxlen байтов из потока ARGF.

Если необязательный аргумент outbuf присутствует, он должен ссылаться на String, который получит данные. outbuf будет содержать только полученные данные после вызова метода, даже если он не был пустым в начале.

Возбуждает EOFError в конце потока ARGF. Поскольку поток ARGF представляет собой конкатенацию нескольких файлов, внутренне EOF происходит для каждого файла. ARGF.readpartial возвращает пустые строки для EOF, кроме последнего, и возбуждает EOFError для последнего.

rewind → 0
Исходный код
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;
}

Перемещает указатель текущего файла в начало входных данных, сбрасывая ARGF.lineno до нуля.

ARGF.readline   #=> "This is line one\n"
ARGF.rewind     #=> 0
ARGF.lineno     #=> 0
ARGF.readline   #=> "This is line one\n"
seek(amount, whence=IO::SEEK_SET) → 0
Исходный код
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);
}

Перемещает указатель в поток ARGF на смещение amount (целое число) в соответствии со значением whence. См. IO#seek для получения дополнительной информации.

set_encoding(ext_enc) → ARGF
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
Исходный код
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;
}

Если указан единственный аргумент, строки, считываемые из ARGF, помечаются указанным кодированием.

Если заданы два имени кодировок, разделенных двоеточием, например, «ascii:utf-8», считываемая строка преобразуется из первой кодировки (внешней кодировки) во вторую кодировку (внутреннюю кодировку), а затем помечается второй кодировкой.

Если указаны два аргумента, они должны быть объектами кодирования или именами кодировок. Опять же, первый задаёт внешнюю кодировку, а второй — внутреннюю кодировку.

Если заданы внешняя и внутренняя кодировки, необязательный аргумент Hash может использоваться для настройки процесса преобразования. Структура этого хэша объясняется в документации String#encode.

Например:

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.
skip → ARGF
Исходный код
static VALUE
argf_skip(VALUE argf)
{
    if (ARGF.init_p && ARGF.next_p == 0) {
        argf_close(argf);
        ARGF.next_p = 1;
    }
    return argf;
}

Устанавливает текущий файл на следующий файл в ARGV. Если больше нет файлов, это не оказывает никакого влияния.

Например:

$ ruby argf.rb foo bar
ARGF.filename  #=> "foo"
ARGF.skip
ARGF.filename  #=> "bar"
tell → Целое число
Исходный код
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);
}

Возвращает текущее смещение (в байтах) текущего файла в ARGF.

ARGF.pos    #=> 0
ARGF.gets   #=> "This is line one\n"
ARGF.pos    #=> 17
Также алиас для: pos
to_a(sep = $/, chomp: false) → массив
to_a(limit, chomp: false) → массив
to_a(sep, limit, chomp: false) → массив

Читает каждый файл в ARGF целиком, возвращая массив, содержащий строки из файлов. Строки предполагается разделить с помощью sep.

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

См. IO.readlines для полного описания всех параметров.

Псевдоним для: readlines
to_i → целое число

Возвращает целое число, представляющее числовой дескриптор файла для текущего файла. Вызывает ArgumentError, если текущего файла нет.

ARGF.fileno    #=> 3
Псевдоним для: fileno
to_io → IO
Исходный код
static VALUE
argf_to_io(VALUE argf)
{
    next_argv();
    ARGF_FORWARD(0, 0);
    return ARGF.current_file;
}

Возвращает объект IO, представляющий текущий файл. Это будет объект File, если текущий файл не является потоком, таким как STDIN.

Например:

ARGF.to_io    #=> #<File:glark.txt>
ARGF.to_io    #=> #<IO:<STDIN>>
to_s → Строка
Исходный код
static VALUE
argf_to_s(VALUE argf)
{
    return rb_str_new2("ARGF");
}

Возвращает «ARGF».

Также алиас для: inspect
to_write_io → io
Исходный код
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);
}

Возвращает экземпляр IO, связанный с ARGF для записи, если режим inplace включён.

write(*objects) → целое число
Исходный код
static VALUE
argf_write(int argc, VALUE *argv, VALUE argf)
{
    return rb_io_writev(argf_write_io(argf), argc, argv);
}

Записывает каждый из указанных objects , если режим inplace включён.

Ruby Core © 1993–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API