класс ARGF
ARGF — это поток, предназначенный для использования в скриптах, обрабатывающих файлы, переданные в качестве аргументов командной строки или через STDIN.
Аргументы, переданные вашему скрипту, хранятся в ARGV Array, по одному аргументу на элемент. ARGF предполагает, что любые аргументы, которые не являются именами файлов, были удалены из ARGV. Например:
$ ruby argf.rb --verbose file1 file2 ARGV #=> ["--verbose", "file1", "file2"] option = ARGV.shift #=> "--verbose" ARGV #=> ["file1", "file2"]
Теперь вы можете использовать ARGF для работы с объединением каждого из этих именованных файлов. Например, ARGF.read вернёт содержимое file1, за которым следует содержимое file2.
После того, как файл в ARGV был прочитан, ARGF удаляет его из Array. Таким образом, после чтения всех файлов ARGV будет пустым.
Вы можете самостоятельно манипулировать ARGV для управления тем, с чем ARGF работает. Если вы удалите файл из ARGV, он будет проигнорирован ARGF; если вы добавите файлы в ARGV, они будут обработаны так, как будто они были указаны в командной строке. Например:
ARGV.replace ["file1"] ARGF.readlines # Returns the contents of file1 as an Array ARGV #=> [] ARGV.replace ["file2", "file3"] ARGF.read # Returns the contents of file2 and file3
Если ARGV пустой, ARGF ведет себя так, как если бы он содержал STDIN, то есть данные, перенаправленные в ваш скрипт. Например:
$ echo "glark" | ruby -e 'p ARGF.read' "glark\n"
Публичные методы экземпляра
static VALUE
argf_argv(VALUE argf)
{
return ARGF.argv;
} Возвращает массив ARGV, который содержит аргументы, переданные в ваш скрипт, по одному на элемент.
Например:
$ ruby argf.rb -v glark.txt ARGF.argv #=> ["-v", "glark.txt"]
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.
static VALUE
argf_binmode_p(VALUE argf)
{
return ARGF.binmode ? Qtrue : Qfalse;
} Возвращает true, если ARGF читается в бинарном режиме; false в противном случае. Для включения бинарного режима используйте ARGF.binmode.
Например:
ARGF.binmode? #=> false ARGF.binmode ARGF.binmode? #=> true
static VALUE
argf_bytes(VALUE argf)
{
rb_warn("ARGF#bytes is deprecated; use #each_byte instead");
if (!rb_block_given_p())
return rb_enumeratorize(argf, ID2SYM(rb_intern("each_byte")), 0, 0);
return argf_each_byte(argf);
} Это устаревшее псевдоним для each_byte.
static VALUE
argf_chars(VALUE argf)
{
rb_warn("ARGF#chars is deprecated; use #each_char instead");
if (!rb_block_given_p())
return rb_enumeratorize(argf, ID2SYM(rb_intern("each_char")), 0, 0);
return argf_each_char(argf);
} Это устаревшее псевдоним для each_char.
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
static VALUE
argf_closed(VALUE argf)
{
next_argv();
ARGF_FORWARD(0, 0);
return rb_io_closed(ARGF.current_file);
} Возвращает true, если текущий файл закрыт; false в противном случае. Используйте ARGF.close для фактического закрытия текущего файла.
static VALUE
argf_codepoints(VALUE argf)
{
rb_warn("ARGF#codepoints is deprecated; use #each_codepoint instead");
if (!rb_block_given_p())
return rb_enumeratorize(argf, ID2SYM(rb_intern("each_codepoint")), 0, 0);
return argf_each_codepoint(argf);
} Это устаревшее псевдоним для each_codepoint.
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 — это Integer, указывающий максимальную длину каждой строки; более длинные строки будут разделены в соответствии с этим ограничением.
Этот метод позволяет вам обрабатывать файлы, предоставленные в командной строке, как один файл, состоящий из конкатенации каждого именованного файла. После возврата последней строки первого файла возвращается первая строка второго файла. Методы ARGF.filename и ARGF.lineno могут использоваться для определения имени файла и номера строки соответственно текущей строки.
Например, следующий код выводит каждую строку каждого именованного файла с префиксом номера строки, отображая имя файла один раз на файл:
ARGF.each_line do |line|
puts ARGF.filename if ARGF.lineno == 1
puts "#{ARGF.lineno}: #{line}"
end
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]
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 может использоваться для определения имени файла, в котором появляется текущий символ.
Если блок не указан, вместо него возвращается перечислитель.
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 может использоваться для определения имени файла, в котором появляется текущая кодовая точка.
Если блок не указан, вместо него возвращается перечислитель.
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 — это Integer, указывающий максимальную длину каждой строки; более длинные строки будут разделены в соответствии с этим ограничением.
Этот метод позволяет вам обрабатывать файлы, предоставленные в командной строке, как один файл, состоящий из конкатенации каждого именованного файла. После возврата последней строки первого файла возвращается первая строка второго файла. Методы ARGF.filename и ARGF.lineno могут использоваться для определения имени файла и номера строки соответственно текущей строки.
Например, следующий код выводит каждую строку каждого именованного файла с префиксом номера строки, отображая имя файла один раз на файл:
ARGF.each_line do |line|
puts ARGF.filename if ARGF.lineno == 1
puts "#{ARGF.lineno}: #{line}"
end
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 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 static VALUE
argf_external_encoding(VALUE argf)
{
if (!RTEST(ARGF.current_file)) {
return rb_enc_from_encoding(rb_default_external_encoding());
}
return rb_io_external_encoding(rb_io_check_io(ARGF.current_file));
} Возвращает внешнее кодирование для файлов, считанных из ARGF, в виде объекта Encoding. Внешнее кодирование — это кодирование текста, как оно хранится в файле. Противоположность — ARGF.internal_encoding, которое является кодировкой, используемой для представления этого текста внутри Ruby.
Чтобы установить внешнее кодирование, используйте ARGF.set_encoding.
Например:
ARGF.external_encoding #=> #<Encoding:UTF-8>
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>
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"
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
static VALUE
argf_getbyte(VALUE argf)
{
VALUE ch;
retry:
if (!next_argv()) return Qnil;
if (!RB_TYPE_P(ARGF.current_file, T_FILE)) {
ch = rb_funcall3(ARGF.current_file, 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
static VALUE
argf_getc(VALUE argf)
{
VALUE ch;
retry:
if (!next_argv()) return Qnil;
if (ARGF_GENERIC_INPUT_P()) {
ch = rb_funcall3(ARGF.current_file, 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
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.
По умолчанию строки предполагаются разделенными $/; чтобы использовать другой символ в качестве разделителя, передайте его в качестве аргумента sep.
Необязательный аргумент limit указывает, сколько символов каждой строки вернуть. По умолчанию возвращаются все символы.
См. IO.readlines для получения подробной информации об аргументах getline_args.
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.
static VALUE
argf_inplace_mode_set(VALUE argf, VALUE val)
{
if (rb_safe_level() >= 1 && OBJ_TAINTED(val))
rb_insecure_operation();
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 заменяет первое вхождение «foo» на «bar», затем новая строка записывается в file.txt.bak.
static VALUE
argf_internal_encoding(VALUE argf)
{
if (!RTEST(ARGF.current_file)) {
return rb_enc_from_encoding(rb_default_external_encoding());
}
return rb_io_internal_encoding(rb_io_check_io(ARGF.current_file));
} Возвращает внутреннее кодирование для строк, считанных из ARGF в виде объекта Encoding.
Если для ARGF.set_encoding были вызваны два кодирования, возвращается второе. В противном случае, если установлено Encoding.default_external, возвращается это значение. В противном случае, если в командной строке было указано внешнее кодирование по умолчанию, используется это значение. Если кодирование неизвестно, возвращается nil.
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
static VALUE
argf_set_lineno(VALUE argf, VALUE val)
{
ARGF.lineno = NUM2INT(val);
ARGF.last_lineno = ARGF.lineno;
return Qnil;
} Устанавливает номер строки для 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
static VALUE
argf_lines(int argc, VALUE *argv, VALUE argf)
{
rb_warn("ARGF#lines is deprecated; use #each_line instead");
if (!rb_block_given_p())
return rb_enumeratorize(argf, ID2SYM(rb_intern("each_line")), argc, argv);
return argf_each_line(argc, argv, argf);
} Это устаревший псевдоним для each_line.
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"
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
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"
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;
}
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;
} Записывает заданный объект(ы) в ios. Возвращает nil.
Поток должен быть открыт для записи. Каждый заданный объект, который не является строкой, будет преобразован путём вызова его метода to_s. При вызове без аргументов, выводит содержимое $_.
Если разделитель полей вывода ($,) не равен nil, он вставляется между объектами. Если разделитель записей вывода ($\) не равен nil, он добавляется к выводу.
$stdout.print("This is ", 100, " percent.\n")
Результат:
This is 100 percent.
VALUE
rb_io_printf(int argc, const VALUE *argv, VALUE out)
{
rb_io_write(out, rb_f_sprintf(argc, argv));
return Qnil;
} Форматирует и записывает в ios, преобразуя параметры в соответствии со строкой формата. Подробнее см. Kernel#sprintf.
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;
} Если obj является Numeric, запишите символ, код которого равен наименее значащему байту obj. Если obj является String, запишите первый символ obj в ios. В противном случае, вызовите TypeError.
$stdout.putc "A" $stdout.putc 65
результат:
AA
VALUE
rb_io_puts(int argc, const VALUE *argv, VALUE out)
{
int i, n;
VALUE line, args[2];
/* if no argument given, print newline. */
if (argc == 0) {
rb_io_write(out, rb_default_rs);
return Qnil;
}
for (i=0; i<argc; i++) {
if (RB_TYPE_P(argv[i], T_STRING)) {
line = argv[i];
goto string;
}
if (rb_exec_recursive(io_puts_ary, argv[i], out)) {
continue;
}
line = rb_obj_as_string(argv[i]);
string:
n = 0;
args[n++] = line;
if (RSTRING_LEN(line) == 0 ||
!rb_str_end_with_asciichar(line, '\n')) {
args[n++] = rb_default_rs;
}
rb_io_writev(out, n, args);
}
return Qnil;
} Записывает заданный объект(ы) в ios. Записывает новую строку после любого объекта, который не заканчивается последовательностью новой строки. Возвращает nil.
Поток должен быть открыт для записи. Если вызвана с аргументом массива, записывает каждый элемент с новой строки. Каждый заданный объект, который не является строкой или массивом, будет преобразован вызовом его метода to_s. Если вызвана без аргументов, выводит единственную новую строку.
$stdout.puts("this", "is", ["a", "test"])
результат:
this is a test
Обратите внимание, что puts всегда использует новые строки и не зависит от разделителя записей вывода ($\).
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) {
len -= slen;
argv[0] = INT2NUM(len);
goto retry;
}
}
return str;
} Считывает length байтов из ARGF. Файлы, указанные в командной строке, конкатенируются и обрабатываются как один файл этим методом, поэтому при вызове без аргументов содержимое этого псевдофайла возвращается полностью.
length должен быть неотрицательным целым числом или nil.
Если length — положительное целое число, read пытается прочитать length байтов без преобразования (в бинарном режиме). Возвращает nil если обнаружен конец файла до прочтения чего-либо. Меньше чем length байт возвращается, если во время чтения обнаружен конец файла. В случае целого значения length результирующая строка всегда в кодировке ASCII-8BIT.
Если length опущено или равно nil, считывает до конца файла и применяется преобразование кодировки, если применимо. Строка возвращается даже если обнаружен конец файла до прочтения каких-либо данных.
Если 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.
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 в режиме без блокировки.
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)
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 = rb_funcall3(ARGF.current_file, 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)
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 указывает, сколько символов каждой строки нужно вернуть. По умолчанию возвращаются все символы.
При достижении конца файла вызывается EOFError.
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 = rb_funcall3(ARGF.current_file, 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, возвращая массив его строк, по одной строке на элемент. Строки предполагаются разделенными sep.
lines = ARGF.readlines lines[0] #=> "This is line one\n"
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 для последнего.
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"
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 для получения дополнительной информации.
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.
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"
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
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 = rb_funcall3(ARGF.current_file, 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, возвращая массив его строк, по одной строке на элемент. Строки предполагается разделять sep.
lines = ARGF.readlines lines[0] #=> "This is line one\n"
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
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>>
static VALUE
argf_to_s(VALUE argf)
{
return rb_str_new2("ARGF");
} Возвращает «ARGF».
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.
static VALUE
argf_write(VALUE argf, VALUE str)
{
return rb_io_write(argf_write_io(argf), str);
} Записывает string, если режим inplace.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.