класс 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 ведет себя так, как будто оно содержит "-", что заставляет ARGF читать из STDIN, т.е. из данных, перенаправленных или введенных в ваш скрипт. Например:
$ echo "glark" | ruby -e 'p ARGF.read' "glark\n" $ echo Glark > file1 $ echo "glark" | ruby -e 'p ARGF.read' -- - file1 "glark\nGlark\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 RBOOL(ARGF.binmode);
} Возвращает true, если ARGF читается в бинарном режиме; false в противном случае. Чтобы включить бинарный режим, используйте ARGF.binmode.
Например:
ARGF.binmode? #=> false ARGF.binmode ARGF.binmode? #=> true
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_p(ARGF.current_file);
} Возвращает true, если текущий файл закрыт; false в противном случае. Используйте ARGF.close, чтобы действительно закрыть текущий файл.
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.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
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 может использоваться для определения имени файла, в котором появляется текущая кодовая точка.
Если блок не задан, вместо этого возвращается перечислитель.
Возвращает перечислитель, который итерируется по каждой строке (разделенной sep, который по умолчанию равен символу перевода строки вашей платформы) каждого файла в ARGV. Если предоставлен блок, каждая строка по очереди будет передаваться блоку, в противном случае возвращается перечислитель. Необязательный аргумент limit — это Integer, указывающий максимальную длину каждой строки; более длинные строки будут разделены в соответствии с этим ограничением.
Этот метод позволяет вам рассматривать файлы, указанные в командной строке, как один файл, состоящий из конкатенации каждого именованного файла. После возвращения последней строки первого файла возвращается первая строка второго файла. Методы 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
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 Возвращает 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)
{
return argf_encoding(argf, rb_io_external_encoding);
} Возвращает кодировку внешнего файла для файлов, считанных из 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 = 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
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
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.
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 (!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».
static VALUE
argf_internal_encoding(VALUE argf)
{
return argf_encoding(argf, rb_io_internal_encoding);
} Возвращает внутреннюю кодировку строк, считанных из 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 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
Возвращает текущее имя файла. «-» возвращается, когда текущий файл — 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"
Возвращает текущий смещение (в байтах) текущего файла в 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);
} Перемещает указатель на позицию, заданную позицией (в байтах) в 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;
}
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
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, см. Спецификации формата.
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
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"
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 положительное целое число,
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 байтов без преобразования (в двоичном режиме). Он возвращает 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.
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 = 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)
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 = 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 для полного описания всех параметров.
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);
} Перемещает указатель к смещению amount (целое число) в потоке ARGF в соответствии со значением 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
Читает каждый файл в ARGF целиком, возвращая массив, содержащий строки из файлов. Строки предполагается разделять sep.
lines = ARGF.readlines lines[0] #=> "This is line one\n"
См. IO.readlines для полного описания всех опций.
Возвращает целое число, представляющее числовой дескриптор файла для текущего файла. Вызывает ArgumentError, если текущего файла нет.
ARGF.fileno #=> 3
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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.