Spec-Zone.ru › Ruby 2.2

модуль Kernel

RubyGems добавляет метод gem, чтобы разрешить активацию определённых версий gem и перезаписывает метод require в Kernel, чтобы сделать gem, как будто они находятся в $LOAD_PATH. Смотрите документацию этих методов для более подробной информации.

Модуль Kernel включается классом Object, поэтому его методы доступны во всех объектах Ruby.

Методы экземпляра модуля Kernel документированы в классе Object, а методы модуля — здесь. Эти методы вызываются без получателя и, следовательно, могут вызываться в функциональной форме:

sprintf "%.1f", 1.234 #=> "1.2"

Публичные методы класса

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 709
def URI(uri)
  if uri.is_a?(URI::Generic)
    uri
  elsif uri = String.try_convert(uri)
    URI.parse(uri)
  else
    raise ArgumentError,
      "bad argument (expected URI object or URI string)"
  end
end

Возвращает uri , преобразованный в объект URI.

open(path [, mode [, perm]] [, opt]) → io или nil Показать исходный код
open(path [, mode [, perm]] [, opt]) {|io| блок } → obj
static VALUE
rb_f_open(int argc, VALUE *argv)
{
    ID to_open = 0;
    int redirect = FALSE;

    if (argc >= 1) {
        CONST_ID(to_open, "to_open");
        if (rb_respond_to(argv[0], to_open)) {
            redirect = TRUE;
        }
        else {
            VALUE tmp = argv[0];
            FilePathValue(tmp);
            if (NIL_P(tmp)) {
                redirect = TRUE;
            }
            else {
                VALUE cmd = check_pipe_command(tmp);
                if (!NIL_P(cmd)) {
                    argv[0] = cmd;
                    return rb_io_s_popen(argc, argv, rb_cIO);
                }
            }
        }
    }
    if (redirect) {
        VALUE io = rb_funcall2(argv[0], to_open, argc-1, argv+1);

        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, io, io_close, io);
        }
        return io;
    }
    return rb_io_s_open(argc, argv, rb_cFile);
}

Создаёт объект IO, подключённый к указанному потоку, файлу или подпроцессу.

Если path не начинается с символа трубы (|), рассматривайте его как имя файла для открытия с указанным режимом (по умолчанию «r»).

Параметр mode является либо строкой, либо целым числом. Если это целое число, оно должно быть побитовым или флагов open(2), таких как File::RDWR или File::EXCL. Если это строка, она либо «fmode», либо «fmode:ext_enc», либо «fmode:ext_enc:int_enc».

См. документацию IO.new для полной документации mode строковых директив.

Если файл создаётся, его начальные разрешения можно установить с помощью параметра perm. Смотрите File.new и страницы руководства open(2) и chmod(2) для описания разрешений.

Если указан блок, он будет вызван с объектом IO в качестве параметра, и IO будет автоматически закрыт по завершении блока. Вызов возвращает значение блока.

Если path начинается с символа трубы ("|"), создаётся подпроцесс, подключённый к вызывающему объекту парой труб. Возвращённый объект IO может использоваться для записи в стандартный ввод и чтения из стандартного вывода этого подпроцесса.

Если команда после символа трубы — одиночный дефис ("|-"), Ruby разветвляется, и этот подпроцесс подключается к родителю. Если команда не "-", подпроцесс выполняет команду.

Когда подпроцесс — Ruby (открыт через "|-"), вызов open возвращает nil. Если с вызовом open связан блок, этот блок выполнится дважды — один раз в родительском процессе и один раз в дочернем.

Параметр блока будет объектом IO в родительском процессе и nil в дочернем. Объект IO родительского процесса будет подключён к $stdin и $stdout дочернего процесса. Подпроцесс будет завершён в конце блока.

Примеры

Чтение из «testfile»:

open("testfile") do |f|
  print f.gets
end

Результат:

This is line one

Открыть подпроцесс и прочитать его вывод:

cmd = open("|date")
print cmd.gets
cmd.close

Результат:

Wed Apr  9 08:56:31 CDT 2003

Открыть подпроцесс, выполняющий ту же программу Ruby:

f = open("|-", "w+")
if f.nil?
  puts "in Child"
  exit
else
  puts "Got: #{f.gets}"
end

Результат:

Got: in Child

Открыть подпроцесс, используя блок для получения объекта IO:

open "|-" do |f|
  if f then
    # parent process
    puts "Got: #{f.gets}"
  else
    # child process
    puts "in Child"
  end
end

Результат:

Got: in Child
Также алиасируется как: open_uri_original_open, open_uri_original_open

Приватные методы класса

open_uri_original_open(*args)
Псевдоним для: open

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

Array(arg) → массив Показать исходный код
static VALUE
rb_f_array(VALUE obj, VALUE arg)
{
    return rb_Array(arg);
}

Возвращает arg в качестве массива.

Сначала пытается вызвать to_ary на arg, затем to_a.

Array(1..5)   #=> [1, 2, 3, 4, 5]
BigDecimal(*args) Показать исходный код
static VALUE
BigDecimal_global_new(int argc, VALUE *argv, VALUE self)
{
    ENTER(1);
    Real *pv;

    GUARD_OBJ(pv, BigDecimal_new(argc, argv));
    if (ToValue(pv)) pv = VpCopy(NULL, pv);
    pv->obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, pv);
    return pv->obj;
}

См. также BigDecimal.new

Complex(x[, y]) → числовой Показать исходный код
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
    return rb_funcall2(rb_cComplex, id_convert, argc, argv);
}

Возвращает x+i*y;

Complex(1, 2)    #=> (1+2i)
Complex('1+2i')  #=> (1+2i)
Complex(nil)     #=> TypeError
Complex(1, nil)  #=> TypeError

Синтаксис строковой формы:

string form = extra spaces , complex , extra spaces ;
complex = real part | [ sign ] , imaginary part
        | real part , sign , imaginary part
        | rational , "@" , rational ;
real part = rational ;
imaginary part = imaginary unit | unsigned rational , imaginary unit ;
rational = [ sign ] , unsigned rational ;
unsigned rational = numerator | numerator , "/" , denominator ;
numerator = integer part | fractional part | integer part , fractional part ;
denominator = digits ;
integer part = digits ;
fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
imaginary unit = "i" | "I" | "j" | "J" ;
sign = "-" | "+" ;
digits = digit , { digit | "_" , digit };
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
extra spaces = ? \s* ? ;

См. String#to_c.

Float(arg) → число с плавающей точкой Показать исходный код
static VALUE
rb_f_float(VALUE obj, VALUE arg)
{
    return rb_Float(arg);
}

Возвращает arg, преобразованный в число с плавающей точкой. Типы Numeric преобразуются напрямую, а остальные, за исключением строк и nil, преобразуются с помощью arg.to_f. Преобразование string с недопустимыми символами приведет к ArgumentError. Преобразование nil генерирует TypeError.

Float(1)                 #=> 1.0
Float("123.456")         #=> 123.456
Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
Float(nil)               #=> TypeError: can't convert nil into Float
Hash(arg) → хэш Показать исходный код
static VALUE
rb_f_hash(VALUE obj, VALUE arg)
{
    return rb_Hash(arg);
}

Преобразует arg в Hash, вызвав arg.to_hash. Возвращает пустой Hash когда arg является nil или [].

Hash([])          #=> {}
Hash(nil)         #=> {}
Hash(key: :value) #=> {:key => :value}
Hash([1, 2, 3])   #=> TypeError
Integer(arg, base=0) → целое число Показать исходный код
static VALUE
rb_f_integer(int argc, VALUE *argv, VALUE obj)
{
    VALUE arg = Qnil;
    int base = 0;

    switch (argc) {
      case 2:
        base = NUM2INT(argv[1]);
      case 1:
        arg = argv[0];
        break;
      default:
        /* should cause ArgumentError */
        rb_scan_args(argc, argv, "11", NULL, NULL);
    }
    return rb_convert_to_integer(arg, base);
}

Преобразует arg в Fixnum или Bignum. Типы Numeric преобразуются напрямую (числа с плавающей точкой отбрасываются). base (0 или от 2 до 36) — основа для целых чисел в строковом представлении. Если arg — это String, когда base опущен или равен нулю, учитываются индикаторы основания (0, 0b, и 0x). В любом случае, строки должны строго соответствовать числовому представлению. Это поведение отличается от String#to_i. Значения, не являющиеся строками, будут преобразованы, сначала попытавшись to_int, затем to_i. Передача nil вызывает TypeError.

Integer(123.999)    #=> 123
Integer("0x1a")     #=> 26
Integer(Time.new)   #=> 1204973019
Integer("0930", 10) #=> 930
Integer("111", 2)   #=> 7
Integer(nil)        #=> TypeError
Pathname(path) → путь Показать исходный код
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
    return rb_class_new_instance(1, &str, rb_cPathname);
}

Создаёт новый объект Pathname из заданной строки, path, и возвращает объект пути.

Для использования этого конструктора необходимо сначала подключить расширение стандартной библиотеки Pathname.

require 'pathname'
Pathname("/home/zzak")
#=> #<Pathname:/home/zzak>

См. также Pathname.new для получения дополнительной информации.

Rational(x[, y]) → числовой Показать исходный код
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
    return rb_funcall2(rb_cRational, id_convert, argc, argv);
}

Возвращает x/y;

Rational(1, 2)   #=> (1/2)
Rational('1/2')  #=> (1/2)
Rational(nil)    #=> TypeError
Rational(1, nil) #=> TypeError

Синтаксис строковой формы:

string form = extra spaces , rational , extra spaces ;
rational = [ sign ] , unsigned rational ;
unsigned rational = numerator | numerator , "/" , denominator ;
numerator = integer part | fractional part | integer part , fractional part ;
denominator = digits ;
integer part = digits ;
fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
sign = "-" | "+" ;
digits = digit , { digit | "_" , digit } ;
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
extra spaces = ? \s* ? ;

См. String#to_r.

String(arg) → строка Показать исходный код
static VALUE
rb_f_string(VALUE obj, VALUE arg)
{
    return rb_String(arg);
}

Возвращает arg в качестве строки.

Сначала пытается вызвать его метод to_str, затем его метод to_s.

String(self)        #=> "main"
String(self.class)  #=> "Object"
String(123456)      #=> "123456"
__callee__ → символ Показать исходный код
static VALUE
rb_f_callee_name(void)
{
    ID fname = prev_frame_callee(); /* need *callee* ID */

    if (fname) {
        return ID2SYM(fname);
    }
    else {
        return Qnil;
    }
}

Возвращает вызываемое имя текущего метода в виде символа. Если вызывается вне метода, возвращает nil.

__dir__ → строка Показать исходный код
static VALUE
f_current_dirname(void)
{
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        return Qnil;
    }
    base = rb_file_dirname(base);
    return base;
}

Возвращает канонизированный абсолютный путь к каталогу файла, из которого вызывается этот метод. Это означает, что символьные ссылки в пути разрешаются. Если __FILE__ равно nil, возвращает nil. Возвращаемое значение равно File.dirname(File.realpath(__FILE__)).

__method__ → символ Показать исходный код
static VALUE
rb_f_method_name(void)
{
    ID fname = prev_frame_func(); /* need *method* ID */

    if (fname) {
        return ID2SYM(fname);
    }
    else {
        return Qnil;
    }
}

Возвращает имя текущего метода в момент определения в виде символа. Если вызывается вне метода, возвращает nil.

`cmd` → строка Показать исходный код
static VALUE
rb_f_backquote(VALUE obj, VALUE str)
{
    VALUE port;
    VALUE result;
    rb_io_t *fptr;

    SafeStringValue(str);
    rb_last_status_clear();
    port = pipe_open_s(str, "r", FMODE_READABLE|DEFAULT_TEXTMODE, NULL);
    if (NIL_P(port)) return rb_str_new(0,0);

    GetOpenFile(port, fptr);
    result = read_all(fptr, remain_size(fptr), Qnil);
    rb_io_close(port);
    rb_io_fptr_finalize(fptr);
    rb_gc_force_recycle(port); /* also guards from premature GC */

    return result;
}

Возвращает стандартный вывод выполнения cmd в дочернем процессе. Встроенный синтаксис %x{...} использует этот метод. Устанавливает $? в состояние процесса.

%x`date`                   #=> "Wed Apr  9 08:56:30 CDT 2003\n"
%x`ls testdir`.split[1]    #=> "main.rb"
%x`echo oops && exit 99`   #=> "oops\n"
$?.exitstatus            #=> 99
abort Показать исходный код
Kernel::abort([msg])
Process::abort([msg])
VALUE
rb_f_abort(int argc, const VALUE *argv)
{
    rb_check_arity(argc, 0, 1);
    if (argc == 0) {
        if (!NIL_P(GET_THREAD()->errinfo)) {
            ruby_error_print();
        }
        rb_exit(EXIT_FAILURE);
    }
    else {
        VALUE args[2];

        args[1] = args[0] = argv[0];
        StringValue(args[0]);
        rb_io_puts(1, args, rb_stderr);
        args[0] = INT2NUM(EXIT_FAILURE);
        rb_exc_raise(rb_class_new_instance(2, args, rb_eSystemExit));
    }

    UNREACHABLE;
}

Немедленно прервать выполнение, фактически вызвав Kernel.exit(false). Если msg задан, он выводится в STDERR перед завершением.

at_exit { блок } → процедура Показать исходный код
static VALUE
rb_f_at_exit(void)
{
    VALUE proc;

    if (!rb_block_given_p()) {
        rb_raise(rb_eArgError, "called without a block");
    }
    proc = rb_block_proc();
    rb_set_end_proc(rb_call_end_proc, proc);
    return proc;
}

Преобразует блок в объект Proc (и тем самым связывает его в момент вызова) и регистрирует его для выполнения при выходе из программы. Если зарегистрировано несколько обработчиков, они выполняются в обратном порядке регистрации.

def do_at_exit(str1)
  at_exit { print str1 }
end
at_exit { puts "cruel world" }
do_at_exit("goodbye ")
exit

выводит:

goodbye cruel world
autoload(модуль, имя_файла) → nil Показать исходный код
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
    VALUE klass = rb_class_real(rb_vm_cbase());
    if (NIL_P(klass)) {
        rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
    }
    return rb_mod_autoload(klass, sym, file);
}

Регистрирует имя_файла для загрузки (с помощью Kernel::require) в первый раз, когда к модулю (который может быть модулем или символом) осуществляется доступ.

autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
autoload?(имя) → Строка или nil Показать исходный код
static VALUE
rb_f_autoload_p(VALUE obj, VALUE sym)
{
    /* use rb_vm_cbase() as same as rb_f_autoload. */
    VALUE klass = rb_vm_cbase();
    if (NIL_P(klass)) {
        return Qnil;
    }
    return rb_mod_autoload_p(klass, sym);
}

Возвращает имя_файла для загрузки, если имя зарегистрировано как autoload.

autoload(:B, "b")
autoload?(:B)            #=> "b"
binding → привязка Показать исходный код
static VALUE
rb_f_binding(VALUE self)
{
    return rb_binding_new();
}

Возвращает объект Binding, описывающий привязки переменных и методов в момент вызова. Этот объект может быть использован при вызове eval для выполнения вычисленной команды в этой среде. См. также описание класса Binding.

def get_binding(param)
  binding
end
b = get_binding("hello")
eval("param", b)   #=> "hello"
block_given? → true или false Показать исходный код
VALUE
rb_f_block_given_p(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;
    cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));

    if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) {
        return Qtrue;
    }
    else {
        return Qfalse;
    }
}

Возвращает true если yield бы выполнил блок в текущем контексте. Форма iterator? слегка устарела.

def try
  if block_given?
    yield
  else
    "no block"
  end
end
try                  #=> "no block"
try { "hello" }      #=> "hello"
try do "hello" end   #=> "hello"
callcc {|cont| block } → obj Показать исходный код
static VALUE
rb_callcc(VALUE self)
{
    volatile int called;
    volatile VALUE val = cont_capture(&called);

    if (called) {
        return val;
    }
    else {
        return rb_yield(val);
    }
}

Генерирует объект Continuation, который передаётся в связанный блок. Вам необходимо require 'continuation' перед использованием этого метода. Выполнение операции cont.call приведёт к возврату из callcc (также при прохождении до конца блока). Значение, возвращаемое callcc, — это значение блока или значение, переданное в cont.call. Дополнительные сведения см. в классе Continuation. Также см. #throw для альтернативного механизма разворачивания стека вызовов.

caller(start=1, length=nil) → массив или nil Показать исходный код
caller(range) → массив или nil
static VALUE
rb_f_caller(int argc, VALUE *argv)
{
    return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 1);
}

Возвращает текущий стек выполнения — массив строк в формате file:line или file:line: in `method'.

Дополнительный параметр start определяет количество начальных записей стека, которые нужно пропустить сверху.

Дополнительный параметр length может использоваться для ограничения количества возвращаемых записей из стека.

Возвращает nil если start больше размера текущего стека выполнения.

Можно также передать диапазон, который вернёт массив, содержащий записи в указанном диапазоне.

def a(skip)
  caller(skip)
end
def b(skip)
  a(skip)
end
def c(skip)
  b(skip)
end
c(0)   #=> ["prog:2:in `a'", "prog:5:in `b'", "prog:8:in `c'", "prog:10:in `<main>'"]
c(1)   #=> ["prog:5:in `b'", "prog:8:in `c'", "prog:11:in `<main>'"]
c(2)   #=> ["prog:8:in `c'", "prog:12:in `<main>'"]
c(3)   #=> ["prog:13:in `<main>'"]
c(4)   #=> []
c(5)   #=> nil
caller_locations(start=1, length=nil) → массив или nil Показать исходный код
caller_locations(range) → массив или nil
static VALUE
rb_f_caller_locations(int argc, VALUE *argv)
{
    return vm_backtrace_to_ary(GET_THREAD(), argc, argv, 1, 1, 0);
}

Возвращает текущий стек выполнения — массив объектов расположения трассировки.

См. Thread::Backtrace::Location для получения дополнительной информации.

Дополнительный параметр start определяет количество начальных записей стека, которые нужно пропустить сверху.

Дополнительный параметр length может использоваться для ограничения количества возвращаемых записей из стека.

Возвращает nil если start больше размера текущего стека выполнения.

Можно также передать диапазон, который вернёт массив, содержащий записи в указанном диапазоне.

catch([tag]) {|tag| block } → obj Показать исходный код
static VALUE
rb_f_catch(int argc, VALUE *argv)
{
    VALUE tag;

    if (argc == 0) {
        tag = rb_obj_alloc(rb_cObject);
    }
    else {
        rb_scan_args(argc, argv, "01", &tag);
    }
    return rb_catch_obj(tag, catch_i, 0);
}

catch выполняет свой блок. Если throw не вызывается, блок выполняется обычно, и catch возвращает значение последнего вычисленного выражения.

catch(1) { 123 }            # => 123

Если throw(tag2, val) вызывается, Ruby ищет в стеке catch блок, у которого tag имеет тот же object_id что и tag2. При обнаружении блок прекращает выполнение и возвращает val (или nil если второй аргумент не был передан в throw).

catch(1) { throw(1, 456) }  # => 456
catch(1) { throw(1) }       # => nil

Если tag передаётся в качестве первого аргумента, catch передаёт его как параметр блока.

catch(1) {|x| x + 2 }       # => 3

Если tag не задан, catch передаёт новый уникальный объект (как из Object.new) в качестве параметра блока. Этот объект затем может использоваться в качестве аргумента для throw, и он будет соответствовать правильному catch блоку.

catch do |obj_A|
  catch do |obj_B|
    throw(obj_B, 123)
    puts "This puts is not reached"
  end

  puts "This puts is displayed"
  456
end

# => 456

catch do |obj_A|
  catch do |obj_B|
    throw(obj_A, 123)
    puts "This puts is still not reached"
  end

  puts "Now this puts is also not reached"
  456
end

# => 123
chomp → $_ Показать исходный код
chomp(string) → $_
static VALUE
rb_f_chomp(int argc, VALUE *argv)
{
    VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chomp"), argc, argv);
    rb_lastline_set(str);
    return str;
}

Эквивалентно $_ = $_.chomp(string). См. String#chomp. Доступно только при использовании опций командной строки -p/-n.

chop → $_ Показать исходный код
static VALUE
rb_f_chop(void)
{
    VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
    rb_lastline_set(str);
    return str;
}

Эквивалентно ($_.dup).chop!, за исключением того, что nil никогда не возвращается. См. String#chop!. Доступно только при использовании опций командной строки -p/-n.

eval(string [, binding [, filename [,lineno]]]) → obj Показать исходный код
VALUE
rb_f_eval(int argc, const VALUE *argv, VALUE self)
{
    VALUE src, scope, vfile, vline;
    VALUE file = Qundef;
    int line = 1;

    rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
    SafeStringValue(src);
    if (argc >= 3) {
        StringValue(vfile);
    }
    if (argc >= 4) {
        line = NUM2INT(vline);
    }

    if (!NIL_P(vfile))
        file = vfile;
    return eval_string(self, src, scope, file, line);
}

Вычисляет выражения Ruby в строке string. Если задан binding, который должен быть объектом Binding, вычисление выполняется в его контексте. Если присутствуют необязательные параметры filename и lineno, они будут использоваться при сообщении об ошибках синтаксиса.

def get_binding(str)
  return binding
end
str = "hello"
eval "str + ' Fred'"                      #=> "hello Fred"
eval "str + ' Fred'", get_binding("bye")  #=> "bye Fred"
exec([env,] command... [,options]) Показать исходный код
VALUE
rb_f_exec(int argc, const VALUE *argv)
{
    VALUE execarg_obj, fail_str;
    struct rb_execarg *eargp;
#define CHILD_ERRMSG_BUFLEN 80
    char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };

    execarg_obj = rb_execarg_new(argc, argv, TRUE);
    eargp = rb_execarg_get(execarg_obj);
    rb_execarg_fixup(execarg_obj);
    fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;

#if defined(__APPLE__) || defined(__HAIKU__)
    rb_exec_without_timer_thread(eargp, errmsg, sizeof(errmsg));
#else
    before_exec_async_signal_safe(); /* async-signal-safe */
    rb_exec_async_signal_safe(eargp, errmsg, sizeof(errmsg));
    preserving_errno(after_exec_async_signal_safe()); /* async-signal-safe */
#endif
    RB_GC_GUARD(execarg_obj);
    if (errmsg[0])
        rb_sys_fail(errmsg);
    rb_sys_fail_str(fail_str);
    return Qnil;                /* dummy */
}

Заменяет текущий процесс выполнением указанной внешней команды, которая может иметь один из следующих форматов:

exec(commandline)

Строка командной строки, которая передаётся в стандартную оболочку.

exec(cmdname, arg1, ...)

Имя команды и один или несколько аргументов (без оболочки).

exec([cmdname, argv0], arg1, ...)

Имя команды, argv и ноль или более аргументов (без оболочки).

В первом формате строка рассматривается как команда, которая подвергается расширению оболочки перед выполнением.

Стандартная оболочка всегда означает "/bin/sh" на системах Unix-подобных, так же как ENV["RUBYSHELL"] (или ENV["COMSPEC"] на Windows NT серии) и аналогичные.

Если строка из первого формата (exec("command")) следует этим простым правилам:

  • нет символов мета-символов

  • нет зарезервированных слов оболочки и нет специальных встроенных функций

  • Ruby вызывает команду напрямую без оболочки

Вы можете принудительно вызвать оболочку, добавив «;» в строку (поскольку «;» — это символ мета-символ).

Обратите внимание, что это поведение можно наблюдать по полученному идентификатору процесса (возвращаемое значение spawn() и IO#pid для IO.popen) — это идентификатор процесса вызываемой команды, а не оболочки.

Во втором формате (exec("command1", "arg1", ...)) первый параметр используется в качестве имени команды, а остальные передаются в качестве параметров команды без расширения оболочки.

В третьем формате (exec(["command", "argv0"], "arg1", ...)) на начало команды помещается массив из двух элементов, первый элемент — это выполняемая команда, а второй аргумент используется в качестве значения argv[0], которое может отображаться в списках процессов.

Для выполнения команды используются системные вызовы exec(2), поэтому исполняемая команда может унаследовать часть окружения исходной программы (включая открытые дескрипторы файлов).

Это поведение изменяется предоставленными env и options параметрами. См. ::spawn для получения подробностей.

Если команда не выполняется (как правило, Errno::ENOENT если её не нашли), возникает исключение SystemCallError.

Этот метод изменяет атрибуты процесса в соответствии с заданными options перед вызовом системной функции exec(2). См. ::spawn для получения дополнительных подробностей о предоставленных options.

Изменённые атрибуты могут сохраняться, когда вызов системной функции exec(2) терпит неудачу.

Например, жёсткие лимиты ресурсов не восстанавливаются.

Рассмотрите создание дочернего процесса с помощью ::spawn или #system, если это недопустимо.

exec "echo *"       # echoes list of files in current directory
# never get here

exec "echo", "*"    # echoes an asterisk
# never get here
exit(status=true) Показать исходный код
Kernel::exit(status=true)
Process::exit(status=true)
VALUE
rb_f_exit(int argc, const VALUE *argv)
{
    VALUE status;
    int istatus;

    if (argc > 0 && rb_scan_args(argc, argv, "01", &status) == 1) {
        istatus = exit_status_code(status);
    }
    else {
        istatus = EXIT_SUCCESS;
    }
    rb_exit(istatus);

    UNREACHABLE;
}

Инициализирует завершение скрипта Ruby, сгенерировав исключение SystemExit. Это исключение может быть перехвачено. Необязательный параметр используется для возврата кода состояния вызывающей среде. true и FALSE status означает успех и неудачу соответственно. Интерпретация других целочисленных значений зависит от системы.

begin
  exit
  puts "never get here"
rescue SystemExit
  puts "rescued a SystemExit exception"
end
puts "after begin block"

производит:

rescued a SystemExit exception
after begin block

Непосредственно перед завершением Ruby выполняет все at_exit функции (см. Kernel::at_exit) и выполняет все финализаторы объектов (см. ObjectSpace.define_finalizer).

at_exit { puts "at_exit function" }
ObjectSpace.define_finalizer("string",  proc { puts "in finalizer" })
exit

производит:

at_exit function
in finalizer
exit!(status=false) Показать исходный код
static VALUE
rb_f_exit_bang(int argc, VALUE *argv, VALUE obj)
{
    VALUE status;
    int istatus;

    if (argc > 0 && rb_scan_args(argc, argv, "01", &status) == 1) {
        istatus = exit_status_code(status);
    }
    else {
        istatus = EXIT_FAILURE;
    }
    _exit(istatus);

    UNREACHABLE;
}

Немедленно завершает процесс. Обработчики выхода не выполняются. status возвращается в базовую систему как код выхода.

Process.exit!(true)
fail Показать исходный код
fail(строка)
fail(исключение [, строка [, массив]])
static VALUE
rb_f_raise(int argc, VALUE *argv)
{
    VALUE err;
    VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];

    argc = extract_raise_opts(argc, argv, opts);
    if (argc == 0) {
        if (*cause != Qundef) {
            rb_raise(rb_eArgError, "only cause is given with no arguments");
        }
        err = get_errinfo();
        if (!NIL_P(err)) {
            argc = 1;
            argv = &err;
        }
    }
    rb_raise_jump(rb_make_exception(argc, argv), *cause);

    UNREACHABLE;
}

Без аргументов, поднимает исключение в $! или поднимает RuntimeError если $! является nil. С одним аргументом String, поднимает RuntimeError со строкой в качестве сообщения. В противном случае, первый параметр должен быть именем класса Exception (или объектом, возвращающим объект Exception при отправке сообщения exception). Необязательный второй параметр задаёт сообщение, связанное с исключением, а третий параметр – массив с информацией о обратных вызовах. Исключение ловится в rescue блоке begin...end.

fork [{ блок }] → целое число или nil Показать исходный код
fork [{ блок }] → целое число или nil
static VALUE
rb_f_fork(VALUE obj)
{
    rb_pid_t pid;

    rb_secure(2);

    switch (pid = rb_fork_ruby(NULL)) {
      case 0:
        rb_thread_atfork();
        if (rb_block_given_p()) {
            int status;

            rb_protect(rb_yield, Qundef, &status);
            ruby_stop(status);
        }
        return Qnil;

      case -1:
        rb_sys_fail("fork(2)");
        return Qnil;

      default:
        return PIDT2NUM(pid);
    }
}

Создаёт дочерний процесс. Если задан блок, этот блок выполняется в дочернем процессе, и дочерний процесс завершается со статусом ноль. В противном случае, вызов fork происходит дважды: один раз в родительском процессе, возвращая идентификатор процесса дочернего, и один раз в дочернем процессе, возвращая nil. Дочерний процесс может завершиться, используя Kernel.exit!, чтобы избежать выполнения любых at_exit функций. Родительский процесс должен использовать Process.wait для сбора статусов завершения своих дочерних процессов или использовать Process.detach для отказа от интереса к их статусу; в противном случае операционная система может накапливать процессы-зомби.

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

Если fork не доступен, Process.respond_to?(:fork) возвращает false.

Обратите внимание, что fork(2) недоступен на некоторых платформах, таких как Windows и NetBSD 4. Поэтому следует использовать spawn() вместо fork().

format(строка_формата [, аргументы...] ) → строка Показать исходный код
VALUE
rb_f_sprintf(int argc, const VALUE *argv)
{
    return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
}

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

Синтаксис последовательности формата:

%[flags][width][.precision]type

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

Символы типа поля:

Field |  Integer Format
------+--------------------------------------------------------------
  b   | Convert argument as a binary number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..1'.
  B   | Equivalent to `b', but uses an uppercase 0B for prefix
      | in the alternative format by #.
  d   | Convert argument as a decimal number.
  i   | Identical to `d'.
  o   | Convert argument as an octal number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..7'.
  u   | Identical to `d'.
  x   | Convert argument as a hexadecimal number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..f' (representing an infinite string of
      | leading 'ff's).
  X   | Equivalent to `x', but uses uppercase letters.

Field |  Float Format
------+--------------------------------------------------------------
  e   | Convert floating point argument into exponential notation
      | with one digit before the decimal point as [-]d.dddddde[+-]dd.
      | The precision specifies the number of digits after the decimal
      | point (defaulting to six).
  E   | Equivalent to `e', but uses an uppercase E to indicate
      | the exponent.
  f   | Convert floating point argument as [-]ddd.dddddd,
      | where the precision specifies the number of digits after
      | the decimal point.
  g   | Convert a floating point number using exponential form
      | if the exponent is less than -4 or greater than or
      | equal to the precision, or in dd.dddd form otherwise.
      | The precision specifies the number of significant digits.
  G   | Equivalent to `g', but use an uppercase `E' in exponent form.
  a   | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
      | which is consisted from optional sign, "0x", fraction part
      | as hexadecimal, "p", and exponential part as decimal.
  A   | Equivalent to `a', but use uppercase `X' and `P'.

Field |  Other Format
------+--------------------------------------------------------------
  c   | Argument is the numeric code for a single character or
      | a single character string itself.
  p   | The valuing of argument.inspect.
  s   | Argument is a string to be substituted.  If the format
      | sequence contains a precision, at most that many characters
      | will be copied.
  %   | A percent sign itself will be displayed.  No argument taken.

Флаги изменяют поведение форматов. Символы флагов:

Flag     | Applies to    | Meaning
---------+---------------+-----------------------------------------
space    | bBdiouxX      | Leave a space at the start of
         | aAeEfgG       | non-negative numbers.
         | (numeric fmt) | For `o', `x', `X', `b' and `B', use
         |               | a minus sign with absolute value for
         |               | negative values.
---------+---------------+-----------------------------------------
(digit)$ | all           | Specifies the absolute argument number
         |               | for this field.  Absolute and relative
         |               | argument numbers cannot be mixed in a
         |               | sprintf string.
---------+---------------+-----------------------------------------
 #       | bBoxX         | Use an alternative format.
         | aAeEfgG       | For the conversions `o', increase the precision
         |               | until the first digit will be `0' if
         |               | it is not formatted as complements.
         |               | For the conversions `x', `X', `b' and `B'
         |               | on non-zero, prefix the result with ``0x'',
         |               | ``0X'', ``0b'' and ``0B'', respectively.
         |               | For `a', `A', `e', `E', `f', `g', and 'G',
         |               | force a decimal point to be added,
         |               | even if no digits follow.
         |               | For `g' and 'G', do not remove trailing zeros.
---------+---------------+-----------------------------------------
+        | bBdiouxX      | Add a leading plus sign to non-negative
         | aAeEfgG       | numbers.
         | (numeric fmt) | For `o', `x', `X', `b' and `B', use
         |               | a minus sign with absolute value for
         |               | negative values.
---------+---------------+-----------------------------------------
-        | all           | Left-justify the result of this conversion.
---------+---------------+-----------------------------------------
0 (zero) | bBdiouxX      | Pad with zeros, not spaces.
         | aAeEfgG       | For `o', `x', `X', `b' and `B', radix-1
         | (numeric fmt) | is used for negative numbers formatted as
         |               | complements.
---------+---------------+-----------------------------------------
*        | all           | Use the next argument as the field width.
         |               | If negative, left-justify the result. If the
         |               | asterisk is followed by a number and a dollar
         |               | sign, use the indicated argument as the width.

Примеры флагов:

# `+' and space flag specifies the sign of non-negative numbers.
sprintf("%d", 123)  #=> "123"
sprintf("%+d", 123) #=> "+123"
sprintf("% d", 123) #=> " 123"

# `#' flag for `o' increases number of digits to show `0'.
# `+' and space flag changes format of negative numbers.
sprintf("%o", 123)   #=> "173"
sprintf("%#o", 123)  #=> "0173"
sprintf("%+o", -123) #=> "-173"
sprintf("%o", -123)  #=> "..7605"
sprintf("%#o", -123) #=> "..7605"

# `#' flag for `x' add a prefix `0x' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%x", 123)   #=> "7b"
sprintf("%#x", 123)  #=> "0x7b"
sprintf("%+x", -123) #=> "-7b"
sprintf("%x", -123)  #=> "..f85"
sprintf("%#x", -123) #=> "0x..f85"
sprintf("%#x", 0)    #=> "0"

# `#' for `X' uses the prefix `0X'.
sprintf("%X", 123)  #=> "7B"
sprintf("%#X", 123) #=> "0X7B"

# `#' flag for `b' add a prefix `0b' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%b", 123)   #=> "1111011"
sprintf("%#b", 123)  #=> "0b1111011"
sprintf("%+b", -123) #=> "-1111011"
sprintf("%b", -123)  #=> "..10000101"
sprintf("%#b", -123) #=> "0b..10000101"
sprintf("%#b", 0)    #=> "0"

# `#' for `B' uses the prefix `0B'.
sprintf("%B", 123)  #=> "1111011"
sprintf("%#B", 123) #=> "0B1111011"

# `#' for `e' forces to show the decimal point.
sprintf("%.0e", 1)  #=> "1e+00"
sprintf("%#.0e", 1) #=> "1.e+00"

# `#' for `f' forces to show the decimal point.
sprintf("%.0f", 1234)  #=> "1234"
sprintf("%#.0f", 1234) #=> "1234."

# `#' for `g' forces to show the decimal point.
# It also disables stripping lowest zeros.
sprintf("%g", 123.4)   #=> "123.4"
sprintf("%#g", 123.4)  #=> "123.400"
sprintf("%g", 123456)  #=> "123456"
sprintf("%#g", 123456) #=> "123456."

Ширина поля – это необязательное целое число, за которым необязательно следует точка и точность. Ширина указывает минимальное количество символов, которые будут записаны в результат для этого поля.

Примеры ширины:

# padding is done by spaces,       width=20
# 0 or radix-1.             <------------------>
sprintf("%20d", 123)   #=> "                 123"
sprintf("%+20d", 123)  #=> "                +123"
sprintf("%020d", 123)  #=> "00000000000000000123"
sprintf("%+020d", 123) #=> "+0000000000000000123"
sprintf("% 020d", 123) #=> " 0000000000000000123"
sprintf("%-20d", 123)  #=> "123                 "
sprintf("%-+20d", 123) #=> "+123                "
sprintf("%- 20d", 123) #=> " 123                "
sprintf("%020x", -123) #=> "..ffffffffffffffff85"

Для числовых полей точность управляет количеством десятичных знаков, отображаемых. Для строковых полей точность определяет максимальное количество символов, копируемых из строки. (Таким образом, последовательность формата %10.10s всегда будет вносить ровно десять символов в результат.)

Примеры точности:

# precision for `d', 'o', 'x' and 'b' is
# minimum number of digits               <------>
sprintf("%20.8d", 123)  #=> "            00000123"
sprintf("%20.8o", 123)  #=> "            00000173"
sprintf("%20.8x", 123)  #=> "            0000007b"
sprintf("%20.8b", 123)  #=> "            01111011"
sprintf("%20.8d", -123) #=> "           -00000123"
sprintf("%20.8o", -123) #=> "            ..777605"
sprintf("%20.8x", -123) #=> "            ..ffff85"
sprintf("%20.8b", -11)  #=> "            ..110101"

# "0x" and "0b" for `#x' and `#b' is not counted for
# precision but "0" for `#o' is counted.  <------>
sprintf("%#20.8d", 123)  #=> "            00000123"
sprintf("%#20.8o", 123)  #=> "            00000173"
sprintf("%#20.8x", 123)  #=> "          0x0000007b"
sprintf("%#20.8b", 123)  #=> "          0b01111011"
sprintf("%#20.8d", -123) #=> "           -00000123"
sprintf("%#20.8o", -123) #=> "            ..777605"
sprintf("%#20.8x", -123) #=> "          0x..ffff85"
sprintf("%#20.8b", -11)  #=> "          0b..110101"

# precision for `e' is number of
# digits after the decimal point           <------>
sprintf("%20.8e", 1234.56789) #=> "      1.23456789e+03"

# precision for `f' is number of
# digits after the decimal point               <------>
sprintf("%20.8f", 1234.56789) #=> "       1234.56789000"

# precision for `g' is number of
# significant digits                          <------->
sprintf("%20.8g", 1234.56789) #=> "           1234.5679"

#                                         <------->
sprintf("%20.8g", 123456789)  #=> "       1.2345679e+08"

# precision for `s' is
# maximum number of characters                    <------>
sprintf("%20.8s", "string test") #=> "            string t"

Примеры:

sprintf("%d %04x", 123, 123)               #=> "123 007b"
sprintf("%08b '%4s'", 123, 123)            #=> "01111011 ' 123'"
sprintf("%1$*2$s %2$d %1$s", "hello", 8)   #=> "   hello 8 hello"
sprintf("%1$*2$s %2$d", "hello", -8)       #=> "hello    -8"
sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23)   #=> "+1.23: 1.23:1.23"
sprintf("%u", -123)                        #=> "-123"

Для более сложной форматировки Ruby поддерживает ссылку по имени. Стиль %<имя> использует стиль форматирования, а стиль %{имя} – нет.

Примеры:

sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
  #=> 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })
  # => "1f"
gem_original_require(путь)

Метод #require до загрузки RubyGems.

Псевдоним для: require
gets(разделитель=$/) → строка или nil Показать исходный код
gets(предел) → строка или nil
gets(разделитель, предел) → строка или nil
static VALUE
rb_f_gets(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_gets(argc, argv, argf);
    }
    return rb_funcall2(argf, idGets, argc, argv);
}

Возвращает (и присваивает $_) следующую строку из списка файлов в ARGV (или $*), или из стандартного ввода, если файлов нет на командной строке. Возвращает nil в конце файла. Необязательный аргумент задаёт разделитель записей. Разделитель включается в содержимое каждой записи. Разделитель nil читает всё содержимое, а разделитель нулевой длины читает вход по абзацам, где абзацы разделены двумя последовательными символами новой строки. Если первый аргумент – целое число или задан необязательный второй аргумент, возвращаемая строка не будет длиннее заданного значения в байтах. Если в ARGV присутствует несколько имён файлов, gets(nil) будет читать содержимое по одному файлу за раз.

ARGV << "testfile"
print while gets

выводит:

This is line one
This is line two
This is line three
And so on...

Стиль программирования, использующий $_ в качестве неявного параметра, постепенно теряет популярность в сообществе Ruby.

global_variables → массив Показать исходный код
VALUE
rb_f_global_variables(void)
{
    VALUE ary = rb_ary_new();
    char buf[2];
    int i;

    st_foreach_safe(rb_global_tbl, gvar_i, ary);
    buf[0] = '$';
    for (i = 1; i <= 9; ++i) {
	buf[1] = (char)(i + '0');
	rb_ary_push(ary, ID2SYM(rb_intern2(buf, 2)));
    }
    return ary;
}

Возвращает массив имён глобальных переменных.

global_variables.grep /std/   #=> [:$stdin, :$stdout, :$stderr]
gsub(шаблон, замена) → $_ Показать исходный код
gsub(шаблон) {|...| блок } → $_
static VALUE
rb_f_gsub(int argc, VALUE *argv)
{
    VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("gsub"), argc, argv);
    rb_lastline_set(str);
    return str;
}

Эквивалентно $_.gsub..., за исключением того, что $_ будет обновляться, если подстановка произойдёт. Доступно только при использовании опции командной строки -p/-n.

iterator? → true или false Показать исходный код
VALUE
rb_f_block_given_p(void)
{
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp = th->cfp;
    cfp = vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));

    if (cfp != 0 && VM_CF_BLOCK_PTR(cfp)) {
        return Qtrue;
    }
    else {
        return Qfalse;
    }
}

Возвращает true, если yield будет выполнять блок в текущем контексте. Форма iterator? слегка устарела.

def try
  if block_given?
    yield
  else
    "no block"
  end
end
try                  #=> "no block"
try { "hello" }      #=> "hello"
try do "hello" end   #=> "hello"
lambda { |...| блок } → a_proc Показать исходный код
VALUE
rb_block_lambda(void)
{
    return proc_new(rb_cProc, TRUE);
}

Эквивалентно Proc.new, за исключением того, что результирующие объекты Proc проверяют количество переданных параметров при вызове.

load(имя_файла, оборачивать=ложь) → истина Показать исходный код
static VALUE
rb_f_load(int argc, VALUE *argv)
{
    VALUE fname, wrap, path, orig_fname;

    rb_scan_args(argc, argv, "11", &fname, &wrap);

    if (RUBY_DTRACE_LOAD_ENTRY_ENABLED()) {
        RUBY_DTRACE_LOAD_ENTRY(StringValuePtr(fname),
                               rb_sourcefile(),
                               rb_sourceline());
    }

    orig_fname = FilePathValue(fname);
    fname = rb_str_encode_ospath(orig_fname);
    path = rb_find_file(fname);
    if (!path) {
        if (!rb_file_load_ok(RSTRING_PTR(fname)))
            load_failed(orig_fname);
        path = fname;
    }
    rb_load_internal(path, RTEST(wrap));

    if (RUBY_DTRACE_LOAD_RETURN_ENABLED()) {
        RUBY_DTRACE_LOAD_RETURN(StringValuePtr(fname),
                               rb_sourcefile(),
                               rb_sourceline());
    }

    return Qtrue;
}

Загружает и выполняет программу Ruby в файле имя_файла. Если имя файла не разрешается в абсолютный путь, файл ищется в каталогах библиотек, перечисленных в $:. Если необязательный параметр оборачивать равен true, загружаемый скрипт будет выполняться в анонимном модуле, защищая глобальное пространство имён вызывающей программы. В любом случае локальные переменные в загружаемом файле не будут переданы в среду загрузки.

local_variables → массив Показать исходный код
static VALUE
rb_f_local_variables(void)
{
    struct local_var_list vars;
    rb_thread_t *th = GET_THREAD();
    rb_control_frame_t *cfp =
        vm_get_ruby_level_caller_cfp(th, RUBY_VM_PREVIOUS_CONTROL_FRAME(th->cfp));
    int i;

    local_var_list_init(&vars);
    while (cfp) {
        if (cfp->iseq) {
            for (i = 0; i < cfp->iseq->local_table_size; i++) {
                local_var_list_add(&vars, cfp->iseq->local_table[i]);
            }
        }
        if (!VM_EP_LEP_P(cfp->ep)) {
            /* block */
            VALUE *ep = VM_CF_PREV_EP(cfp);

            if (vm_collect_local_variables_in_heap(th, ep, &vars)) {
                break;
            }
            else {
                while (cfp->ep != ep) {
                    cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp);
                }
            }
        }
        else {
            break;
        }
    }
    return local_var_list_finish(&vars);
}

Возвращает имена текущих локальных переменных.

fred = 1
for i in 1..10
   # ...
end
local_variables   #=> [:fred, :i]
loop { блок } Показать исходный код
loop → итерируемый_объект
static VALUE
rb_f_loop(VALUE self)
{
    RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
    rb_rescue2(loop_i, (VALUE)0, 0, 0, rb_eStopIteration, (VALUE)0);
    return Qnil;                /* dummy */
}

Повторяет выполнение блока.

Если блок не задан, возвращается итерируемый объект.

loop do
  print "Input: "
  line = gets
  break if !line or line =~ /^qQ/
  # ...
end

StopIteration, вызванный в блоке, прерывает цикл.

p(объект) → объект Показать исходный код
p(объект1, объект2, ...) → [объект, ...]
p() → nil
static VALUE
rb_f_p(int argc, VALUE *argv, VALUE self)
{
    struct rb_f_p_arg arg;
    arg.argc = argc;
    arg.argv = argv;

    return rb_uninterruptible(rb_f_p_internal, (VALUE)&arg);
}

Для каждого объекта напрямую выводит объект.inspect за ним следует новая строка в стандартный вывод программы.

S = Struct.new(:name, :state)
s = S['dave', 'TX']
p s

выводит:

#<S name="dave", state="TX">
pretty_inspect() Показать исходный код
# File lib/pp.rb, line 11
def pretty_inspect
  PP.pp(self, '')
end

Возвращает красиво отформатированный объект в виде строки.

Для использования этого метода необходимо сначала загрузить модуль PP:

require 'pp'

Дополнительную информацию см. в модуле PP.

print(obj, ...) → nil Показать исходный код
static VALUE
rb_f_print(int argc, const VALUE *argv)
{
    rb_io_print(argc, argv, rb_stdout);
    return Qnil;
}

Выводит каждый объект по очереди в $stdout. Если разделитель полей вывода ($,) не nil, его содержимое будет отображаться между каждым полем. Если разделитель записей вывода ($\) не nil, он будет добавлен в вывод. Если аргументы не указаны, выводит $_. Объекты, которые не являются строками, будут преобразованы путем вызова их метода to_s.

print "cat", [1,2,3], 99, "\n"
$, = ", "
$\ = "\n"
print "cat", [1,2,3], 99

Результат:

cat12399
cat, 1, 2, 3, 99
printf(io, string [, obj ... ]) → nil Показать исходный код
printf(string [, obj ... ]) → nil
static VALUE
rb_f_printf(int argc, VALUE *argv)
{
    VALUE out;

    if (argc == 0) return Qnil;
    if (RB_TYPE_P(argv[0], T_STRING)) {
        out = rb_stdout;
    }
    else {
        out = argv[0];
        argv++;
        argc--;
    }
    rb_io_write(out, rb_f_sprintf(argc, argv));

    return Qnil;
}

Эквивалентно:

io.write(sprintf(string, obj, ...))

или

$stdout.write(sprintf(string, obj, ...))
proc { |...| block } → a_proc Показать исходный код
VALUE
rb_block_proc(void)
{
    return proc_new(rb_cProc, FALSE);
}

Эквивалентно Proc.new.

putc(int) → int Показать исходный код
static VALUE
rb_f_putc(VALUE recv, VALUE ch)
{
    if (recv == rb_stdout) {
        return rb_io_putc(recv, ch);
    }
    return rb_funcall2(rb_stdout, rb_intern("putc"), 1, &ch);
}

Эквивалентно:

$stdout.putc(int)

Обратитесь к документации для IO#putc для получения важной информации о многобайтовых символах.

puts(obj, ...) → nil Показать исходный код
static VALUE
rb_f_puts(int argc, VALUE *argv, VALUE recv)
{
    if (recv == rb_stdout) {
        return rb_io_puts(argc, argv, recv);
    }
    return rb_funcall2(rb_stdout, rb_intern("puts"), argc, argv);
}

Эквивалентно

$stdout.puts(obj, ...)
raise Показать исходный код
raise(string)
raise(exception [, string [, array]])
static VALUE
rb_f_raise(int argc, VALUE *argv)
{
    VALUE err;
    VALUE opts[raise_max_opt], *const cause = &opts[raise_opt_cause];

    argc = extract_raise_opts(argc, argv, opts);
    if (argc == 0) {
        if (*cause != Qundef) {
            rb_raise(rb_eArgError, "only cause is given with no arguments");
        }
        err = get_errinfo();
        if (!NIL_P(err)) {
            argc = 1;
            argv = &err;
        }
    }
    rb_raise_jump(rb_make_exception(argc, argv), *cause);

    UNREACHABLE;
}

Без аргументов, поднимает исключение в $! или поднимает RuntimeError если $! является nil. С одним аргументом – строкой, поднимает RuntimeError со строкой в качестве сообщения. В противном случае, первый параметр должен быть именем класса Exception (или объектом, который возвращает объект Exception при отправке сообщения exception). Необязательный второй параметр задаёт сообщение, связанное с исключением, а третий — массив информации обратного вызова. Исключение перехватывается в rescue блоке begin...end.

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
rand(max=0) → number Показать исходный код
static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
    VALUE v, vmax, r;
    struct MT *mt = default_mt();

    if (argc == 0) goto zero_arg;
    rb_scan_args(argc, argv, "01", &vmax);
    if (NIL_P(vmax)) goto zero_arg;
    if ((v = rand_range(mt, vmax)) != Qfalse) {
        return v;
    }
    vmax = rb_to_int(vmax);
    if (vmax == INT2FIX(0) || NIL_P(r = rand_int(mt, vmax, 0))) {
      zero_arg:
        return DBL2NUM(genrand_real(mt));
    }
    return r;
}

Если вызывается без аргумента или если max.to_i.abs == 0, rand возвращает псевдослучайное число с плавающей точкой между 0,0 и 1,0 включительно 0,0 и исключая 1,0.

rand        #=> 0.2725926052826416

Когда max.abs больше или равно 1, rand возвращает псевдослучайное целое число больше или равное 0 и меньшее max.to_i.abs.

rand(100)   #=> 12

Когда max является диапазоном, rand возвращает случайное число, где range.member?(number) == true.

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

rand(-100) # => 87
rand(-0.5) # => 0.8130921818028143
rand(1.9)  # equivalent to rand(1), which is always 0

#srand может использоваться для обеспечения воспроизводимости последовательностей случайных чисел при различных запусках программы.

См. также Random#rand.

readline(sep=$/) → string Показать исходный код
readline(limit) → string
readline(sep, limit) → string
static VALUE
rb_f_readline(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_readline(argc, argv, argf);
    }
    return rb_funcall2(argf, rb_intern("readline"), argc, argv);
}

Эквивалентно Kernel::gets, за исключением того, что readline генерирует EOFError в конце файла.

readlines(sep=$/) → array Показать исходный код
readlines(limit) → array
readlines(sep, limit) → array
static VALUE
rb_f_readlines(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_readlines(argc, argv, argf);
    }
    return rb_funcall2(argf, rb_intern("readlines"), argc, argv);
}

Возвращает массив, содержащий строки, возвращаемые вызовом Kernel.gets(sep) до конца файла.

require_relative(string) → true or false Показать исходный код
VALUE
rb_f_require_relative(VALUE obj, VALUE fname)
{
    VALUE base = rb_current_realfilepath();
    if (NIL_P(base)) {
        rb_loaderror("cannot infer basepath");
    }
    base = rb_file_dirname(base);
    return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
}

Ruby пытается загрузить библиотеку с именем string относительно пути файла, который её требует. Если путь к файлу определить невозможно, генерируется исключение LoadError. Если файл загружен, возвращается true, в противном случае — false.

select(read_array [, write_array [, error_array [, timeout]]]) → array or nil Показать исходный код
static VALUE
rb_f_select(int argc, VALUE *argv, VALUE obj)
{
    VALUE timeout;
    struct select_args args;
    struct timeval timerec;
    int i;

    rb_scan_args(argc, argv, "13", &args.read, &args.write, &args.except, &timeout);
    if (NIL_P(timeout)) {
        args.timeout = 0;
    }
    else {
        timerec = rb_time_interval(timeout);
        args.timeout = &timerec;
    }

    for (i = 0; i < numberof(args.fdsets); ++i)
        rb_fd_init(&args.fdsets[i]);

    return rb_ensure(select_call, (VALUE)&args, select_end, (VALUE)&args);
}

Вызывает системный вызов select(2). Отслеживает заданные массивы объектов IO, ожидает, пока один или несколько из них IO готовы для чтения, записи и имеют ожидающие исключения соответственно, и возвращает массив, содержащий массивы этих объектов IO. Возвращает nil, если необязательное значение timeout задано и ни один объект IO не готов в течение timeout секунд.

IO.select просматривает буфер объектов IO для проверки возможности чтения. Если буфер IO не пуст, IO.select немедленно сообщает о возможности чтения. Такой «просмотр» происходит только для объектов IO. Он не выполняется для объектов, подобных IO, таких как OpenSSL::SSL::SSLSocket.

Лучший способ использовать IO.select — вызвать его после неблокирующих методов, таких как read_nonblock, write_nonblock и т. д. Эти методы могут вызывать исключения, расширенные IO::WaitReadable или IO::WaitWritable. Модули сообщают вызывающей стороне, как она должна ожидать, используя IO.select. Если возбуждается IO::WaitReadable, вызывающая сторона должна ожидать чтения. Если возбуждается IO::WaitWritable, вызывающая сторона должна ожидать записи.

Таким образом, блокирующее чтение (readpartial) можно эмулировать, используя read_nonblock и IO.select следующим образом:

begin
  result = io_like.read_nonblock(maxlen)
rescue IO::WaitReadable
  IO.select([io_like])
  retry
rescue IO::WaitWritable
  IO.select(nil, [io_like])
  retry
end

В особенности, сочетание неблокирующих методов и IO.select предпочтительно для объектов типа IO, таких как OpenSSL::SSL::SSLSocket. У них есть метод to_io для возвращения базового объекта IO. IO.select вызывает to_io для получения дескриптора файла, на котором нужно ожидать.

Это означает, что уведомление о возможности чтения, полученное с помощью IO.select, не обязательно означает возможность чтения из объекта OpenSSL::SSL::SSLSocket.

В большинстве случаев буфер OpenSSL::SSL::SSLSocket хранит некоторые данные. IO.select не видит буфера. Поэтому IO.select может заблокироваться, когда OpenSSL::SSL::SSLSocket#readpartial не блокируется.

Однако существуют и более сложные ситуации.

SSL — это протокол, представляющий собой последовательность записей. Запись состоит из нескольких байтов. Поэтому удалённая сторона SSL отправляет частичную запись, IO.select сообщает о возможности чтения, но OpenSSL::SSL::SSLSocket не может декодировать байт, и OpenSSL::SSL::SSLSocket#readpartial заблокируется.

Также удалённая сторона может запросить переподключение SSL, что заставляет локальный движок SSL записать некоторые данные. Это означает, что OpenSSL::SSL::SSLSocket#readpartial может вызвать системный вызов write и заблокироваться. В такой ситуации OpenSSL::SSL::SSLSocket#read_nonblock возбуждает IO::WaitWritable вместо блокировки. Таким образом, вызывающая сторона должна ожидать готовности к записи, как показано в примере выше.

Сочетание неблокирующих методов и IO.select также полезно для потоков, таких как tty, pipe, сокеты, когда несколько процессов читают из потока.

Наконец, разработчики ядра Linux не гарантируют, что возможность чтения с помощью select(2) означает возможность чтения с помощью последующего read(2), даже для одного процесса. См. руководство select(2) в системе GNU/Linux.

Вызов IO.select перед IO#readpartial хорошо работает в обычных ситуациях. Однако это не лучший способ использования IO.select.

Возможность записи, уведомляемая select(2), не показывает, сколько байтов можно записать. Метод IO#write блокируется до тех пор, пока не будет записана вся строка. Таким образом, IO#write(two or more bytes) может заблокироваться после уведомления о возможности записи IO.select. Требуется IO#write_nonblock для избежания блокировки.

Блокирующая запись (write) может быть эмулирована, используя write_nonblock и IO.select следующим образом: IO::WaitReadable также нужно перехватывать для переподключения SSL в OpenSSL::SSL::SSLSocket.

while 0 < string.bytesize
  begin
    written = io_like.write_nonblock(string)
  rescue IO::WaitReadable
    IO.select([io_like])
    retry
  rescue IO::WaitWritable
    IO.select(nil, [io_like])
    retry
  end
  string = string.byteslice(written..-1)
end

Параметры

read_array

массив объектов IO, которые ожидают готовности к чтению

write_array

массив объектов IO, которые ожидают готовности к записи

error_array

массив объектов IO, которые ожидают исключений

timeout

числовое значение в секундах

Пример

rp, wp = IO.pipe
mesg = "ping "
100.times {
  # IO.select follows IO#read.  Not the best way to use IO.select.
  rs, ws, = IO.select([rp], [wp])
  if r = rs[0]
    ret = r.read(5)
    print ret
    case ret
    when /ping/
      mesg = "pong\n"
    when /pong/
      mesg = "ping "
    end
  end
  if w = ws[0]
    w.write(mesg)
  end
}

выводит:

ping pong
ping pong
ping pong
(snipped)
ping
set_trace_func(proc) → proc Показать исходный код
set_trace_func(nil) → nil
static VALUE
set_trace_func(VALUE obj, VALUE trace)
{

    rb_remove_event_hook(call_trace_func);

    if (NIL_P(trace)) {
        return Qnil;
    }

    if (!rb_obj_is_proc(trace)) {
        rb_raise(rb_eTypeError, "trace_func needs to be Proc");
    }

    rb_add_event_hook(call_trace_func, RUBY_EVENT_ALL, trace);
    return trace;
}

Устанавливает proc в качестве обработчика трассировки или отключает трассировку, если параметр равен nil.

Примечание: этот метод устарел, используйте TracePoint вместо него.

proc принимает до шести параметров:

  • имя события

  • имя файла

  • номер строки

  • идентификатор объекта

  • связывание

  • имя класса

proc вызывается всякий раз, когда происходит событие.

События:

c-call

вызов C-функции

c-return

возврат из C-функции

call

вызов Ruby-метода

class

начало определения класса или модуля

end

окончание определения класса или модуля

line

выполнение кода в новой строке

raise

возбуждение исключения

return

возврат из Ruby-метода

Трассировка отключается в контексте proc.

  class Test
  def test
    a = 1
    b = 2
  end
  end

  set_trace_func proc { |event, file, line, id, binding, classname|
     printf "%8s %s:%-2d %10s %8s\n", event, file, line, id, classname
  }
  t = Test.new
  t.test

    line prog.rb:11               false
  c-call prog.rb:11        new    Class
  c-call prog.rb:11 initialize   Object
c-return prog.rb:11 initialize   Object
c-return prog.rb:11        new    Class
    line prog.rb:12               false
    call prog.rb:2        test     Test
    line prog.rb:3        test     Test
    line prog.rb:4        test     Test
  return prog.rb:4        test     Test
sleep([duration]) → fixnum Показать исходный код
static VALUE
rb_f_sleep(int argc, VALUE *argv)
{
    time_t beg, end;

    beg = time(0);
    if (argc == 0) {
        rb_thread_sleep_forever();
    }
    else {
        rb_check_arity(argc, 0, 1);
        rb_thread_wait_for(rb_time_interval(argv[0]));
    }

    end = time(0) - beg;

    return INT2FIX(end);
}

Приостанавливает текущую нить на duration секунд (может быть любым числом, включая Float с дробными секундами). Возвращает фактическое количество проспанных секунд (округленное), которое может быть меньше запрошенного, если другая нить вызывает Thread#run. Без аргумента, sleep() будет спать вечно.

Time.new    #=> 2008-03-08 19:56:19 +0900
sleep 1.2   #=> 1
Time.new    #=> 2008-03-08 19:56:20 +0900
sleep 1.9   #=> 2
Time.new    #=> 2008-03-08 19:56:22 +0900
spawn([env,] command... [,options]) → pid Показать исходный код
spawn([env,] command... [,options]) → pid
static VALUE
rb_f_spawn(int argc, VALUE *argv)
{
    rb_pid_t pid;
    char errmsg[CHILD_ERRMSG_BUFLEN] = { '\0' };
    VALUE execarg_obj, fail_str;
    struct rb_execarg *eargp;

    execarg_obj = rb_execarg_new(argc, argv, TRUE);
    eargp = rb_execarg_get(execarg_obj);
    rb_execarg_fixup(execarg_obj);
    fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;

    pid = rb_spawn_process(eargp, errmsg, sizeof(errmsg));
    RB_GC_GUARD(execarg_obj);

    if (pid == -1) {
        const char *prog = errmsg;
        if (!prog[0]) {
            rb_sys_fail_str(fail_str);
        }
        rb_sys_fail(prog);
    }
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
    return PIDT2NUM(pid);
#else
    return Qnil;
#endif
}

spawn выполняет указанную команду и возвращает её pid.

pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
Process.wait pid

pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
Process.wait pid

Этот метод аналогичен методу #system, но не ожидает завершения команды.

Родительский процесс должен использовать Process.wait для получения статуса завершения своего дочернего процесса или использовать Process.detach для отмены интереса к их статусу; в противном случае операционная система может накапливать зомби-процессы.

spawn имеет набор опций для указания атрибутов процесса:

env: hash
  name => val : set the environment variable
  name => nil : unset the environment variable
command...:
  commandline                 : command line string which is passed to the standard shell
  cmdname, arg1, ...          : command name and one or more arguments (This form does not use the shell. See below for caveats.)
  [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
options: hash
  clearing environment variables:
    :unsetenv_others => true   : clear environment variables except specified by env
    :unsetenv_others => false  : don't clear (default)
  process group:
    :pgroup => true or 0 : make a new process group
    :pgroup => pgid      : join to specified process group
    :pgroup => nil       : don't change the process group (default)
  create new process group: Windows only
    :new_pgroup => true  : the new process is the root process of a new process group
    :new_pgroup => false : don't create a new process group (default)
  resource limit: resourcename is core, cpu, data, etc.  See Process.setrlimit.
    :rlimit_resourcename => limit
    :rlimit_resourcename => [cur_limit, max_limit]
  umask:
    :umask => int
  redirection:
    key:
      FD              : single file descriptor in child process
      [FD, FD, ...]   : multiple file descriptor in child process
    value:
      FD                        : redirect to the file descriptor in parent process
      string                    : redirect to file with open(string, "r" or "w")
      [string]                  : redirect to file with open(string, File::RDONLY)
      [string, open_mode]       : redirect to file with open(string, open_mode, 0644)
      [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
      [:child, FD]              : redirect to the redirected file descriptor
      :close                    : close the file descriptor in child process
    FD is one of follows
      :in     : the file descriptor 0 which is the standard input
      :out    : the file descriptor 1 which is the standard output
      :err    : the file descriptor 2 which is the standard error
      integer : the file descriptor of specified the integer
      io      : the file descriptor specified as io.fileno
  file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
    :close_others => true  : don't inherit
  current directory:
    :chdir => str

  The 'cmdname, arg1, ...' form does not use the shell. However,
  on different OSes, different things are provided as built-in
  commands. An example of this is 'echo', which is a built-in
  on Windows, but is a normal program on Linux and Mac OS X.
  This means that `Process.spawn 'echo', '%Path%'` will display
  the contents of the `%Path%` environment variable on Windows,
  but `Process.spawn 'echo', '$PATH'` prints the literal '$PATH'.

Если в качестве env передаётся хэш, среда обновляется методом env перед exec(2) в дочернем процессе. Если пара в env имеет значение nil, переменная удаляется.

# set FOO as BAR and unset BAZ.
pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)

Если в качестве options передаётся хэш, он задаёт группу процессов, создание новой группы процессов, ограничения ресурсов, текущий каталог, umask и перенаправления для дочернего процесса. Также можно указать очистку переменных среды.

Ключ :unsetenv_others в options указывает на очистку переменных среды, кроме тех, которые заданы env.

pid = spawn(command, :unsetenv_others=>true) # no environment variable
pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only

Ключ :pgroup в options задаёт группу процессов. Соответствующее значение должно быть true, нулём или положительным целым числом. true и ноль означают, что процесс должен быть лидером процесса новой группы процессов. Другие значения задают группу процессов, к которой он принадлежит.

pid = spawn(command, :pgroup=>true) # process leader
pid = spawn(command, :pgroup=>10) # belongs to the process group 10

Ключ :new_pgroup в options указывает на передачу флага CREATE_NEW_PROCESS_GROUP в CreateProcessW(), который является функцией API Windows. Эта опция предназначена только для Windows. true означает, что новый процесс является корневым процессом новой группы процессов. Новый процесс имеет отключённый CTRL+C. Этот флаг необходим для Process.kill(:SIGINT, pid) в дочернем процессе. По умолчанию :new_pgroup равен false.

pid = spawn(command, :new_pgroup=>true)  # new process group
pid = spawn(command, :new_pgroup=>false) # same process group

Ключ :rlimit_foo задаёт ограничение ресурса. foo должен быть одним из типов ресурсов, таких как core. Соответствующее значение должно быть целым числом или массивом, содержащим одно или два целых числа: аналогично аргументам cur_limit и max_limit для Process.setrlimit.

cur, max = Process.getrlimit(:CORE)
pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
pid = spawn(command, :rlimit_core=>max) # enable core dump
pid = spawn(command, :rlimit_core=>0) # never dump core.

Ключ :umask в options задаёт значение umask.

pid = spawn(command, :umask=>077)

Ключи :in, :out, :err, целое число, объект IO и массив задают перенаправление. Перенаправление сопоставляет дескриптор файла в дочернем процессе.

Например, stderr можно объединить со stdout следующим образом:

pid = spawn(command, :err=>:out)
pid = spawn(command, 2=>1)
pid = spawn(command, STDERR=>:out)
pid = spawn(command, STDERR=>STDOUT)

Ключи хэша задают дескриптор файла в дочернем процессе, запущенном spawn. :err, 2 и STDERR задают поток стандартной ошибки (stderr).

Значения хэша задают дескриптор файла в родительском процессе, вызвавшем spawn. :out, 1 и STDOUT задают поток стандартного вывода (stdout).

В приведенном выше примере стандартный вывод в дочернем процессе не указан. Поэтому он наследуется от родительского процесса.

Поток стандартного ввода (stdin) можно указать с помощью :in, 0 и STDIN.

Имя файла можно указать в качестве значения хэша.

pid = spawn(command, :in=>"/dev/null") # read mode
pid = spawn(command, :out=>"/dev/null") # write mode
pid = spawn(command, :err=>"log") # write mode
pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
pid = spawn(command, 3=>"/dev/null") # read mode

Для stdout и stderr (и их комбинации) он открывается в режиме записи. В противном случае используется режим чтения.

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

pid = spawn(command, :in=>["file"]) # read mode is assumed
pid = spawn(command, :in=>["file", "r"])
pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
pid = spawn(command, :out=>["log", "w", 0600])
pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])

Массив указывает имя файла, флаги и разрешения. Флаги могут быть строкой или целым числом. Если флаги опущены или nil, предполагается File::RDONLY. Разрешения должны быть целым числом. Если разрешения опущены или nil, предполагается 0644.

Если в качестве ключа хэша указан массив объектов IO и целых чисел, все элементы перенаправляются.

# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, [:out, :err]=>["log", "w"])

Другой способ объединения нескольких дескрипторов файлов — [:child, fd]. [:child, fd] означает дескриптор файла в дочернем процессе. Это отличается от fd. Например, :err=>:out означает перенаправление дочернего stderr в родительский stdout. Но :err=>[:child, :out] означает перенаправление дочернего stderr в дочерний stdout. Они отличаются, если stdout перенаправлен в дочернем процессе следующим образом.

# stdout and stderr is redirected to log file.
# The file "log" is opened just once.
pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])

[:child, :out] можно использовать для объединения stderr с stdout в IO.popen. В этом случае IO.popen перенаправляет stdout в канал в дочернем процессе, а [:child, :out] относится к перенаправленному stdout.

io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
p io.read #=> "out\nerr\n"

Ключ :chdir в options задаёт текущий каталог.

pid = spawn(command, :chdir=>"/var/tmp")

По умолчанию spawn закрывает все неопределённые дескрипторы, кроме стандартных (0, 1 и 2). Это поведение задаётся опцией :close_others. :close_others не влияет на стандартные дескрипторы, которые закрываются только если :close указано явно.

pid = spawn(command, :close_others=>true)  # close 3,4,5,... (default)
pid = spawn(command, :close_others=>false) # don't close 3,4,5,...

По умолчанию :close_others равно true для spawn и IO.popen.

Обратите внимание, что дескрипторы, у которых флаг close-on-exec уже установлен, закрываются независимо от опции :close_others.

Поэтому IO.pipe и spawn можно использовать как IO.popen.

# similar to r = IO.popen(command)
r, w = IO.pipe
pid = spawn(command, :out=>w)   # r, w is closed in the child process.
w.close

:close указывается в качестве значения хэша для закрытия дескриптора файла индивидуально.

f = open(foo)
system(command, f=>:close)        # don't inherit f.

Если нужно унаследовать дескриптор файла, можно использовать io=>io.

# valgrind has --log-fd option for log destination.
# log_w=>log_w indicates log_w.fileno inherits to child process.
log_r, log_w = IO.pipe
pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
log_w.close
p log_r.read

Также возможно обмен дескрипторами файлов.

pid = spawn(command, :out=>:err, :err=>:out)

Ключи хэша задают дескрипторы файлов в дочернем процессе. Значения хэша задают дескрипторы файлов в родительском процессе. Таким образом, выше указано перенаправление stdout и stderr. Внутренне spawn использует дополнительный дескриптор файла для решения таких циклических сопоставлений дескрипторов файлов.

См. Kernel.exec для стандартной оболочки.

sprintf(format_string [, arguments...] ) → string Показать исходный код
VALUE
rb_f_sprintf(int argc, const VALUE *argv)
{
    return rb_str_format(argc - 1, argv + 1, GETNTHARG(0));
}

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

Синтаксис последовательности формата следующий.

%[flags][width][.precision]type

Последовательность формата состоит из символа процента, за которым следуют необязательные флаги, ширина и индикаторы точности, а затем завершающий символ типа поля. Тип поля управляет тем, как соответствующий sprintf аргумент будет интерпретирован, а флаги изменяют эту интерпретацию.

Символы типа поля:

Field |  Integer Format
------+--------------------------------------------------------------
  b   | Convert argument as a binary number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..1'.
  B   | Equivalent to `b', but uses an uppercase 0B for prefix
      | in the alternative format by #.
  d   | Convert argument as a decimal number.
  i   | Identical to `d'.
  o   | Convert argument as an octal number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..7'.
  u   | Identical to `d'.
  x   | Convert argument as a hexadecimal number.
      | Negative numbers will be displayed as a two's complement
      | prefixed with `..f' (representing an infinite string of
      | leading 'ff's).
  X   | Equivalent to `x', but uses uppercase letters.

Field |  Float Format
------+--------------------------------------------------------------
  e   | Convert floating point argument into exponential notation
      | with one digit before the decimal point as [-]d.dddddde[+-]dd.
      | The precision specifies the number of digits after the decimal
      | point (defaulting to six).
  E   | Equivalent to `e', but uses an uppercase E to indicate
      | the exponent.
  f   | Convert floating point argument as [-]ddd.dddddd,
      | where the precision specifies the number of digits after
      | the decimal point.
  g   | Convert a floating point number using exponential form
      | if the exponent is less than -4 or greater than or
      | equal to the precision, or in dd.dddd form otherwise.
      | The precision specifies the number of significant digits.
  G   | Equivalent to `g', but use an uppercase `E' in exponent form.
  a   | Convert floating point argument as [-]0xh.hhhhp[+-]dd,
      | which is consisted from optional sign, "0x", fraction part
      | as hexadecimal, "p", and exponential part as decimal.
  A   | Equivalent to `a', but use uppercase `X' and `P'.

Field |  Other Format
------+--------------------------------------------------------------
  c   | Argument is the numeric code for a single character or
      | a single character string itself.
  p   | The valuing of argument.inspect.
  s   | Argument is a string to be substituted.  If the format
      | sequence contains a precision, at most that many characters
      | will be copied.
  %   | A percent sign itself will be displayed.  No argument taken.

Флаги изменяют поведение форматов. Символы флагов:

Flag     | Applies to    | Meaning
---------+---------------+-----------------------------------------
space    | bBdiouxX      | Leave a space at the start of
         | aAeEfgG       | non-negative numbers.
         | (numeric fmt) | For `o', `x', `X', `b' and `B', use
         |               | a minus sign with absolute value for
         |               | negative values.
---------+---------------+-----------------------------------------
(digit)$ | all           | Specifies the absolute argument number
         |               | for this field.  Absolute and relative
         |               | argument numbers cannot be mixed in a
         |               | sprintf string.
---------+---------------+-----------------------------------------
 #       | bBoxX         | Use an alternative format.
         | aAeEfgG       | For the conversions `o', increase the precision
         |               | until the first digit will be `0' if
         |               | it is not formatted as complements.
         |               | For the conversions `x', `X', `b' and `B'
         |               | on non-zero, prefix the result with ``0x'',
         |               | ``0X'', ``0b'' and ``0B'', respectively.
         |               | For `a', `A', `e', `E', `f', `g', and 'G',
         |               | force a decimal point to be added,
         |               | even if no digits follow.
         |               | For `g' and 'G', do not remove trailing zeros.
---------+---------------+-----------------------------------------
+        | bBdiouxX      | Add a leading plus sign to non-negative
         | aAeEfgG       | numbers.
         | (numeric fmt) | For `o', `x', `X', `b' and `B', use
         |               | a minus sign with absolute value for
         |               | negative values.
---------+---------------+-----------------------------------------
-        | all           | Left-justify the result of this conversion.
---------+---------------+-----------------------------------------
0 (zero) | bBdiouxX      | Pad with zeros, not spaces.
         | aAeEfgG       | For `o', `x', `X', `b' and `B', radix-1
         | (numeric fmt) | is used for negative numbers formatted as
         |               | complements.
---------+---------------+-----------------------------------------
*        | all           | Use the next argument as the field width.
         |               | If negative, left-justify the result. If the
         |               | asterisk is followed by a number and a dollar
         |               | sign, use the indicated argument as the width.

Примеры флагов:

# `+' and space flag specifies the sign of non-negative numbers.
sprintf("%d", 123)  #=> "123"
sprintf("%+d", 123) #=> "+123"
sprintf("% d", 123) #=> " 123"

# `#' flag for `o' increases number of digits to show `0'.
# `+' and space flag changes format of negative numbers.
sprintf("%o", 123)   #=> "173"
sprintf("%#o", 123)  #=> "0173"
sprintf("%+o", -123) #=> "-173"
sprintf("%o", -123)  #=> "..7605"
sprintf("%#o", -123) #=> "..7605"

# `#' flag for `x' add a prefix `0x' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%x", 123)   #=> "7b"
sprintf("%#x", 123)  #=> "0x7b"
sprintf("%+x", -123) #=> "-7b"
sprintf("%x", -123)  #=> "..f85"
sprintf("%#x", -123) #=> "0x..f85"
sprintf("%#x", 0)    #=> "0"

# `#' for `X' uses the prefix `0X'.
sprintf("%X", 123)  #=> "7B"
sprintf("%#X", 123) #=> "0X7B"

# `#' flag for `b' add a prefix `0b' for non-zero numbers.
# `+' and space flag disables complements for negative numbers.
sprintf("%b", 123)   #=> "1111011"
sprintf("%#b", 123)  #=> "0b1111011"
sprintf("%+b", -123) #=> "-1111011"
sprintf("%b", -123)  #=> "..10000101"
sprintf("%#b", -123) #=> "0b..10000101"
sprintf("%#b", 0)    #=> "0"

# `#' for `B' uses the prefix `0B'.
sprintf("%B", 123)  #=> "1111011"
sprintf("%#B", 123) #=> "0B1111011"

# `#' for `e' forces to show the decimal point.
sprintf("%.0e", 1)  #=> "1e+00"
sprintf("%#.0e", 1) #=> "1.e+00"

# `#' for `f' forces to show the decimal point.
sprintf("%.0f", 1234)  #=> "1234"
sprintf("%#.0f", 1234) #=> "1234."

# `#' for `g' forces to show the decimal point.
# It also disables stripping lowest zeros.
sprintf("%g", 123.4)   #=> "123.4"
sprintf("%#g", 123.4)  #=> "123.400"
sprintf("%g", 123456)  #=> "123456"
sprintf("%#g", 123456) #=> "123456."

Ширина поля — это необязательное целое число, за которым необязательно следует точка и точность. Ширина задаёт минимальное количество символов, которые будут записаны в результат для данного поля.

Примеры ширины:

# padding is done by spaces,       width=20
# 0 or radix-1.             <------------------>
sprintf("%20d", 123)   #=> "                 123"
sprintf("%+20d", 123)  #=> "                +123"
sprintf("%020d", 123)  #=> "00000000000000000123"
sprintf("%+020d", 123) #=> "+0000000000000000123"
sprintf("% 020d", 123) #=> " 0000000000000000123"
sprintf("%-20d", 123)  #=> "123                 "
sprintf("%-+20d", 123) #=> "+123                "
sprintf("%- 20d", 123) #=> " 123                "
sprintf("%020x", -123) #=> "..ffffffffffffffff85"

Для числовых полей точность управляет количеством десятичных знаков, отображаемых. Для строковых полей точность определяет максимальное количество символов, копируемых из строки. (Таким образом, последовательность формата %10.10s всегда внесёт ровно десять символов в результат.)

Примеры точности:

# precision for `d', 'o', 'x' and 'b' is
# minimum number of digits               <------>
sprintf("%20.8d", 123)  #=> "            00000123"
sprintf("%20.8o", 123)  #=> "            00000173"
sprintf("%20.8x", 123)  #=> "            0000007b"
sprintf("%20.8b", 123)  #=> "            01111011"
sprintf("%20.8d", -123) #=> "           -00000123"
sprintf("%20.8o", -123) #=> "            ..777605"
sprintf("%20.8x", -123) #=> "            ..ffff85"
sprintf("%20.8b", -11)  #=> "            ..110101"

# "0x" and "0b" for `#x' and `#b' is not counted for
# precision but "0" for `#o' is counted.  <------>
sprintf("%#20.8d", 123)  #=> "            00000123"
sprintf("%#20.8o", 123)  #=> "            00000173"
sprintf("%#20.8x", 123)  #=> "          0x0000007b"
sprintf("%#20.8b", 123)  #=> "          0b01111011"
sprintf("%#20.8d", -123) #=> "           -00000123"
sprintf("%#20.8o", -123) #=> "            ..777605"
sprintf("%#20.8x", -123) #=> "          0x..ffff85"
sprintf("%#20.8b", -11)  #=> "          0b..110101"

# precision for `e' is number of
# digits after the decimal point           <------>
sprintf("%20.8e", 1234.56789) #=> "      1.23456789e+03"

# precision for `f' is number of
# digits after the decimal point               <------>
sprintf("%20.8f", 1234.56789) #=> "       1234.56789000"

# precision for `g' is number of
# significant digits                          <------->
sprintf("%20.8g", 1234.56789) #=> "           1234.5679"

#                                         <------->
sprintf("%20.8g", 123456789)  #=> "       1.2345679e+08"

# precision for `s' is
# maximum number of characters                    <------>
sprintf("%20.8s", "string test") #=> "            string t"

Примеры:

sprintf("%d %04x", 123, 123)               #=> "123 007b"
sprintf("%08b '%4s'", 123, 123)            #=> "01111011 ' 123'"
sprintf("%1$*2$s %2$d %1$s", "hello", 8)   #=> "   hello 8 hello"
sprintf("%1$*2$s %2$d", "hello", -8)       #=> "hello    -8"
sprintf("%+g:% g:%-g", 1.23, 1.23, 1.23)   #=> "+1.23: 1.23:1.23"
sprintf("%u", -123)                        #=> "-123"

Для более сложного форматирования Ruby поддерживает ссылку по имени. Стиль %<имя>s использует стиль форматирования, но стиль %{имя} — нет.

Примеры:

sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
  #=> 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })
  # => "1f"
srand(number = Random.new_seed) → old_seed Показать исходный код
static VALUE
rb_f_srand(int argc, VALUE *argv, VALUE obj)
{
    VALUE seed, old;
    rb_random_t *r = &default_rand;

    if (argc == 0) {
        seed = random_seed();
    }
    else {
        rb_scan_args(argc, argv, "01", &seed);
    }
    old = r->seed;
    r->seed = rand_init(&r->mt, seed);

    return old;
}

Инициализирует генератор псевдослучайных чисел системы Random::DEFAULT с number. Возвращается предыдущее значение seed.

Если number опущено, генератор инициализируется с помощью источника энтропии, предоставленного операционной системой (если доступен /dev/urandom в системах Unix или криптографический модуль RSA в Windows), который затем комбинируется со временем, идентификатором процесса и порядковым номером.

srand можно использовать для обеспечения повторяемости последовательностей псевдослучайных чисел при различных запусках программы. Установив seed в известное значение, программы можно сделать детерминированными во время тестирования.

srand 1234               # => 268519324636777531569100071560086917274
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
[ rand(10), rand(1000) ] # => [4, 664]
srand 1234               # => 1234
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
sub(pattern, replacement) → $_ Показать исходный код
sub(pattern) {|...| block } → $_
static VALUE
rb_f_sub(int argc, VALUE *argv)
{
    VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("sub"), argc, argv);
    rb_lastline_set(str);
    return str;
}

Эквивалентно $_.sub(args), за исключением того, что $_ будет обновлён, если произойдёт подстановка. Доступно только при использовании опций командной строки -p/-n.

syscall(num [, args...]) → integer Показать исходный код
static VALUE
rb_f_syscall(int argc, VALUE *argv)
{
#ifdef atarist
    VALUE arg[13]; /* yes, we really need that many ! */
#else
    VALUE arg[8];
#endif
#if SIZEOF_VOIDP == 8 && defined(HAVE___SYSCALL) && SIZEOF_INT != 8 /* mainly *BSD */
# define SYSCALL __syscall
# define NUM2SYSCALLID(x) NUM2LONG(x)
# define RETVAL2NUM(x) LONG2NUM(x)
# if SIZEOF_LONG == 8
    long num, retval = -1;
# elif SIZEOF_LONG_LONG == 8
    long long num, retval = -1;
# else
#  error ---->> it is asserted that __syscall takes the first argument and returns retval in 64bit signed integer. <<----
# endif
#elif defined(__linux__)
# define SYSCALL syscall
# define NUM2SYSCALLID(x) NUM2LONG(x)
# define RETVAL2NUM(x) LONG2NUM(x)
    /*
     * Linux man page says, syscall(2) function prototype is below.
     *
     *     int syscall(int number, ...);
     *
     * But, it's incorrect. Actual one takes and returned long. (see unistd.h)
     */
    long num, retval = -1;
#else
# define SYSCALL syscall
# define NUM2SYSCALLID(x) NUM2INT(x)
# define RETVAL2NUM(x) INT2NUM(x)
    int num, retval = -1;
#endif
    int i;

    if (RTEST(ruby_verbose)) {
        rb_warning("We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
    }

    rb_secure(2);
    if (argc == 0)
        rb_raise(rb_eArgError, "too few arguments for syscall");
    if (argc > numberof(arg))
        rb_raise(rb_eArgError, "too many arguments for syscall");
    num = NUM2SYSCALLID(argv[0]); ++argv;
    for (i = argc - 1; i--; ) {
        VALUE v = rb_check_string_type(argv[i]);

        if (!NIL_P(v)) {
            SafeStringValue(v);
            rb_str_modify(v);
            arg[i] = (VALUE)StringValueCStr(v);
        }
        else {
            arg[i] = (VALUE)NUM2LONG(argv[i]);
        }
    }

    switch (argc) {
      case 1:
        retval = SYSCALL(num);
        break;
      case 2:
        retval = SYSCALL(num, arg[0]);
        break;
      case 3:
        retval = SYSCALL(num, arg[0],arg[1]);
        break;
      case 4:
        retval = SYSCALL(num, arg[0],arg[1],arg[2]);
        break;
      case 5:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3]);
        break;
      case 6:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4]);
        break;
      case 7:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]);
        break;
      case 8:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]);
        break;
#ifdef atarist
      case 9:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7]);
        break;
      case 10:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7], arg[8]);
        break;
      case 11:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7], arg[8], arg[9]);
        break;
      case 12:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7], arg[8], arg[9], arg[10]);
        break;
      case 13:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7], arg[8], arg[9], arg[10], arg[11]);
        break;
      case 14:
        retval = SYSCALL(num, arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6],
          arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]);
        break;
#endif
    }

    if (retval == -1)
        rb_sys_fail(0);
    return RETVAL2NUM(retval);
#undef SYSCALL
#undef NUM2SYSCALLID
#undef RETVAL2NUM
}

Вызывает функцию операционной системы, идентифицируемую по num, и возвращает результат функции или вызывает SystemCallError, если произошла ошибка.

Аргументы функции могут следовать за num. Они должны быть либо объектами String, либо объектами Integer. Объект String передаётся как указатель на последовательность байтов. Объект Integer передаётся как целое число, размер разряда которого совпадает с размером указателя. Может быть передано до девяти параметров (14 на Atari-ST).

Функция, идентифицируемая по num, зависит от системы. В некоторых системах Unix эти числа могут быть получены из заголовочного файла, называемого syscall.h.

syscall 4, 1, "hello\n", 6   # '4' is write(2) on our box

выдает:

hello

Вызов syscall на платформе, у которой нет возможности вызова произвольной системной функции, приводит к ошибке NotImplementedError.

Примечание: syscall в значительной степени небезопасно и не переносимо. Не стесняйтесь экспериментировать. Библиотека DL (Fiddle) предпочтительнее для более безопасного и переносимого программирования.

system([env,] command... [,options]) → true, false or nil Показать исходный код
static VALUE
rb_f_system(int argc, VALUE *argv)
{
    rb_pid_t pid;
    int status;

#if defined(SIGCLD) && !defined(SIGCHLD)
# define SIGCHLD SIGCLD
#endif

#ifdef SIGCHLD
    RETSIGTYPE (*chfunc)(int);

    rb_last_status_clear();
    chfunc = signal(SIGCHLD, SIG_DFL);
#endif
    pid = rb_spawn_internal(argc, argv, NULL, 0);
#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
    if (pid > 0) {
        int ret, status;
        ret = rb_waitpid(pid, &status, 0);
        if (ret == (rb_pid_t)-1)
            rb_sys_fail("Another thread waited the process started by system().");
    }
#endif
#ifdef SIGCHLD
    signal(SIGCHLD, chfunc);
#endif
    if (pid < 0) {
        return Qnil;
    }
    status = PST2INT(rb_last_status_get());
    if (status == EXIT_SUCCESS) return Qtrue;
    return Qfalse;
}

Выполняет command… в дочернем процессе. command… имеет один из следующих форматов.

commandline                 : command line string which is passed to the standard shell
cmdname, arg1, ...          : command name and one or more arguments (no shell)
[cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)

system возвращает true, если команда завершается с нулевым кодом выхода, false, если с ненулевым. Возвращает nil, если выполнение команды завершается ошибкой. Статус ошибки доступен в $?. Аргументы обрабатываются так же, как и для Kernel.spawn.

Аргументы hash, env и options аналогичны exec и spawn. Подробности см. в Kernel.spawn.

system("echo *")
system("echo", "*")

выдает:

config.h main.rb
*

См. Kernel.exec для стандартной оболочки.

test(cmd, file1 [, file2] ) → obj Показать исходный код
static VALUE
rb_f_test(int argc, VALUE *argv)
{
    int cmd;

    if (argc == 0) rb_check_arity(argc, 2, 3);
    cmd = NUM2CHR(argv[0]);
    if (cmd == 0) {
      unknown:
        /* unknown command */
        if (ISPRINT(cmd)) {
            rb_raise(rb_eArgError, "unknown command '%s%c'", cmd == '\'' || cmd == '\\' ? "\\" : "", cmd);
        }
        else {
            rb_raise(rb_eArgError, "unknown command \"\\x%02X\"", cmd);
        }
    }
    if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
        CHECK(1);
        switch (cmd) {
          case 'b':
            return rb_file_blockdev_p(0, argv[1]);

          case 'c':
            return rb_file_chardev_p(0, argv[1]);

          case 'd':
            return rb_file_directory_p(0, argv[1]);

          case 'e':
            return rb_file_exist_p(0, argv[1]);

          case 'f':
            return rb_file_file_p(0, argv[1]);

          case 'g':
            return rb_file_sgid_p(0, argv[1]);

          case 'G':
            return rb_file_grpowned_p(0, argv[1]);

          case 'k':
            return rb_file_sticky_p(0, argv[1]);

          case 'l':
            return rb_file_symlink_p(0, argv[1]);

          case 'o':
            return rb_file_owned_p(0, argv[1]);

          case 'O':
            return rb_file_rowned_p(0, argv[1]);

          case 'p':
            return rb_file_pipe_p(0, argv[1]);

          case 'r':
            return rb_file_readable_p(0, argv[1]);

          case 'R':
            return rb_file_readable_real_p(0, argv[1]);

          case 's':
            return rb_file_size_p(0, argv[1]);

          case 'S':
            return rb_file_socket_p(0, argv[1]);

          case 'u':
            return rb_file_suid_p(0, argv[1]);

          case 'w':
            return rb_file_writable_p(0, argv[1]);

          case 'W':
            return rb_file_writable_real_p(0, argv[1]);

          case 'x':
            return rb_file_executable_p(0, argv[1]);

          case 'X':
            return rb_file_executable_real_p(0, argv[1]);

          case 'z':
            return rb_file_zero_p(0, argv[1]);
        }
    }

    if (strchr("MAC", cmd)) {
        struct stat st;
        VALUE fname = argv[1];

        CHECK(1);
        if (rb_stat(fname, &st) == -1) {
            FilePathValue(fname);
            rb_sys_fail_path(fname);
        }

        switch (cmd) {
          case 'A':
            return stat_atime(&st);
          case 'M':
            return stat_mtime(&st);
          case 'C':
            return stat_ctime(&st);
        }
    }

    if (cmd == '-') {
        CHECK(2);
        return rb_file_identical_p(0, argv[1], argv[2]);
    }

    if (strchr("=<>", cmd)) {
        struct stat st1, st2;

        CHECK(2);
        if (rb_stat(argv[1], &st1) < 0) return Qfalse;
        if (rb_stat(argv[2], &st2) < 0) return Qfalse;

        switch (cmd) {
          case '=':
            if (st1.st_mtime == st2.st_mtime) return Qtrue;
            return Qfalse;

          case '>':
            if (st1.st_mtime > st2.st_mtime) return Qtrue;
            return Qfalse;

          case '<':
            if (st1.st_mtime < st2.st_mtime) return Qtrue;
            return Qfalse;
        }
    }
    goto unknown;
}

Использует символ cmd для выполнения различных проверок на file1 (первая таблица ниже) или на file1 и file2 (вторая таблица).

Проверки на файл File для одного файла:

Cmd    Returns   Meaning
"A"  | Time    | Last access time for file1
"b"  | boolean | True if file1 is a block device
"c"  | boolean | True if file1 is a character device
"C"  | Time    | Last change time for file1
"d"  | boolean | True if file1 exists and is a directory
"e"  | boolean | True if file1 exists
"f"  | boolean | True if file1 exists and is a regular file
"g"  | boolean | True if file1 has the \CF{setgid} bit
     |         | set (false under NT)
"G"  | boolean | True if file1 exists and has a group
     |         | ownership equal to the caller's group
"k"  | boolean | True if file1 exists and has the sticky bit set
"l"  | boolean | True if file1 exists and is a symbolic link
"M"  | Time    | Last modification time for file1
"o"  | boolean | True if file1 exists and is owned by
     |         | the caller's effective uid
"O"  | boolean | True if file1 exists and is owned by
     |         | the caller's real uid
"p"  | boolean | True if file1 exists and is a fifo
"r"  | boolean | True if file1 is readable by the effective
     |         | uid/gid of the caller
"R"  | boolean | True if file is readable by the real
     |         | uid/gid of the caller
"s"  | int/nil | If file1 has nonzero size, return the size,
     |         | otherwise return nil
"S"  | boolean | True if file1 exists and is a socket
"u"  | boolean | True if file1 has the setuid bit set
"w"  | boolean | True if file1 exists and is writable by
     |         | the effective uid/gid
"W"  | boolean | True if file1 exists and is writable by
     |         | the real uid/gid
"x"  | boolean | True if file1 exists and is executable by
     |         | the effective uid/gid
"X"  | boolean | True if file1 exists and is executable by
     |         | the real uid/gid
"z"  | boolean | True if file1 exists and has a zero length

Проверки, использующие два файла:

"-"  | boolean | True if file1 and file2 are identical
"="  | boolean | True if the modification times of file1
     |         | and file2 are equal
"<"  | boolean | True if the modification time of file1
     |         | is prior to that of file2
">"  | boolean | True if the modification time of file1
     |         | is after that of file2
throw(tag [, obj]) Показать исходный код
static VALUE
rb_f_throw(int argc, VALUE *argv)
{
    VALUE tag, value;

    rb_scan_args(argc, argv, "11", &tag, &value);
    rb_throw_obj(tag, value);
    UNREACHABLE;
}

Переносит управление в конец активного catch блока, ожидая tag. Вызывает UncaughtThrowError, если нет блока catch для tag. Дополнительный второй параметр предоставляет возвращаемое значение для блока catch, которое в противном случае по умолчанию равно nil. Примеры см. в Kernel::catch.

trace_var(symbol, cmd ) → nil Показать исходный код
trace_var(symbol) {|val| block } → nil
VALUE
rb_f_trace_var(int argc, const VALUE *argv)
{
    VALUE var, cmd;
    struct global_entry *entry;
    struct trace_var *trace;

    if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
	cmd = rb_block_proc();
    }
    if (NIL_P(cmd)) {
	return rb_f_untrace_var(argc, argv);
    }
    entry = rb_global_entry(rb_to_id(var));
    if (OBJ_TAINTED(cmd)) {
	rb_raise(rb_eSecurityError, "Insecure: tainted variable trace");
    }
    trace = ALLOC(struct trace_var);
    trace->next = entry->var->trace;
    trace->func = rb_trace_eval;
    trace->data = cmd;
    trace->removed = 0;
    entry->var->trace = trace;

    return Qnil;
}

Управляет отслеживанием присваиваний глобальным переменным. Параметр symbol идентифицирует переменную (как имя строки, так и идентификатор символа). cmd (может быть строкой или объектом Proc) или блок выполняются всякий раз, когда переменная присваивается. Блок или объект Proc получает новое значение переменной в качестве параметра. Также см. Kernel::untrace_var.

trace_var :$_, proc {|v| puts "$_ is now '#{v}'" }
$_ = "hello"
$_ = ' there'

выдает:

$_ is now 'hello'
$_ is now ' there'
trap( signal, command ) → obj Показать исходный код
trap( signal ) {| | block } → obj
static VALUE
sig_trap(int argc, VALUE *argv)
{
    int sig;
    sighandler_t func;
    VALUE cmd;

    rb_secure(2);
    rb_check_arity(argc, 1, 2);

    sig = trap_signm(argv[0]);
    if (reserved_signal_p(sig)) {
        const char *name = signo2signm(sig);
        if (name)
            rb_raise(rb_eArgError, "can't trap reserved signal: SIG%s", name);
        else
            rb_raise(rb_eArgError, "can't trap reserved signal: %d", sig);
    }

    if (argc == 1) {
        cmd = rb_block_proc();
        func = sighandler;
    }
    else {
        cmd = argv[1];
        func = trap_handler(&cmd, sig);
    }

    if (OBJ_TAINTED(cmd)) {
        rb_raise(rb_eSecurityError, "Insecure: tainted signal trap");
    }

    return trap(sig, func, cmd);
}

Устанавливает обработку сигналов. Первый параметр — имя сигнала (строка, например, «SIGALRM», «SIGUSR1» и т. д.) или номер сигнала. Символы «SIG» могут быть опущены из имени сигнала. Команда или блок определяют код, который будет выполнен при поднятии сигнала. Если команда равна строке «IGNORE» или «SIG_IGN», сигнал будет проигнорирован. Если команда равна «DEFAULT» или «SIG_DFL», будет вызвана обработчик по умолчанию Ruby. Если команда равна «EXIT», сценарий завершится сигналом. Если команда равна «SYSTEM_DEFAULT», будет вызван обработчик по умолчанию операционной системы. В противном случае будет выполнена указанная команда или блок. Специальное имя сигнала «EXIT» или номер сигнала ноль будет вызвано непосредственно перед завершением программы. trap возвращает предыдущий обработчик для данного сигнала.

Signal.trap(0, proc { puts "Terminating: #{$$}" })
Signal.trap("CLD")  { puts "Child died" }
fork && Process.wait

выдает:

Terminating: 27461
Child died
Terminating: 27460
untrace_var(symbol [, cmd] ) → array or nil Показать исходный код
VALUE
rb_f_untrace_var(int argc, const VALUE *argv)
{
    VALUE var, cmd;
    ID id;
    struct global_entry *entry;
    struct trace_var *trace;
    st_data_t data;

    rb_scan_args(argc, argv, "11", &var, &cmd);
    id = rb_check_id(&var);
    if (!id) {
	rb_name_error_str(var, "undefined global variable %"PRIsVALUE"", QUOTE(var));
    }
    if (!st_lookup(rb_global_tbl, (st_data_t)id, &data)) {
	rb_name_error(id, "undefined global variable %"PRIsVALUE"", QUOTE_ID(id));
    }

    trace = (entry = (struct global_entry *)data)->var->trace;
    if (NIL_P(cmd)) {
	VALUE ary = rb_ary_new();

	while (trace) {
	    struct trace_var *next = trace->next;
	    rb_ary_push(ary, (VALUE)trace->data);
	    trace->removed = 1;
	    trace = next;
	}

	if (!entry->var->block_trace) remove_trace(entry->var);
	return ary;
    }
    else {
	while (trace) {
	    if (trace->data == cmd) {
		trace->removed = 1;
		if (!entry->var->block_trace) remove_trace(entry->var);
		return rb_ary_new3(1, cmd);
	    }
	    trace = trace->next;
	}
    }
    return Qnil;
}

Удаляет отслеживание для указанной команды в данной глобальной переменной и возвращает nil. Если команда не указана, удаляет всё отслеживание для этой переменной и возвращает массив, содержащий команды, которые были удалены.

warn(msg, ...) → nil Показать исходный код
static VALUE
rb_warn_m(int argc, VALUE *argv, VALUE exc)
{
    if (!NIL_P(ruby_verbose) && argc > 0) {
        rb_io_puts(argc, argv, rb_stderr);
    }
    return Qnil;
}

Отображает каждый из заданных сообщений, после чего разделитель записей в STDERR, если предупреждения отключены (например, с флагом -W0).

  warn("warning 1", "warning 2")

<em>produces:</em>

  warning 1
  warning 2

Приватные методы экземпляра

JSON(object, *args) Показать исходный код
# File ext/json/lib/json/common.rb, line 466
def JSON(object, *args)
  if object.respond_to? :to_str
    JSON.parse(object.to_str, args.first)
  else
    JSON.generate(object, args.first)
  end
end

Если object является строкой, разобрать строку и вернуть результат разбора в виде структуры данных Ruby. В противном случае, сгенерировать текстовое представление JSON из объекта структуры данных Ruby и вернуть его.

Аргумент opts передается в функцию генерации/разбора соответственно. Смотрите документацию по генерации и разбору для получения дополнительной информации.

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 709
def URI(uri)
  if uri.is_a?(URI::Generic)
    uri
  elsif uri = String.try_convert(uri)
    URI.parse(uri)
  else
    raise ArgumentError,
      "bad argument (expected URI object or URI string)"
  end
end

Возвращает uri , преобразованный в объект URI.

gem(gem_name, *requirements) Показать исходный код
# File lib/rubygems/core_ext/kernel_gem.rb, line 43
def gem(gem_name, *requirements) # :doc:
  skip_list = (ENV['GEM_SKIP'] || "").split(/:/)
  raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name

  if gem_name.kind_of? Gem::Dependency
    unless Gem::Deprecate.skip
      warn "#{Gem.location_of_caller.join ':'}:Warning: Kernel.gem no longer "           "accepts a Gem::Dependency object, please pass the name "           "and requirements directly"
    end

    requirements = gem_name.requirement
    gem_name = gem_name.name
  end

  dep = Gem::Dependency.new(gem_name, *requirements)

  loaded = Gem.loaded_specs[gem_name]

  return false if loaded && dep.matches_spec?(loaded)

  spec = dep.to_spec

  Gem::LOADED_SPECS_MUTEX.synchronize {
    spec.activate
  } if spec
end

Используйте #gem для активации определенной версии gem_name.

requirements — это список требований к версии, которым должна соответствовать указанная библиотека, чаще всего «= example.version.number». Смотрите Gem::Requirement для того, как указать требование к версии.

Если вы будете активировать последнюю версию библиотеки, нет необходимости вызывать #gem, #require сделает это за вас.

#gem возвращает true, если библиотека была активирована, в противном случае — false. Если библиотека не найдена, не соответствует требованиям к версии или уже активирована другая версия, будет возбуждено исключение.

#gem должен вызываться **до** любых инструкций require (иначе RubyGems может загрузить конфликтующую версию библиотеки).

#gem загружает предварительные версии только тогда, когда указаны предварительные requirements:

gem 'rake', '>= 1.1.a', '< 2'

В более старых версиях RubyGems переменная окружения GEM_SKIP могла использоваться для пропуска активации указанных библиотек, например, для тестирования изменений, которые еще не были установлены. Теперь RubyGems использует -I и переменную среды RUBYLIB для пропуска активации библиотеки.

Пример:

GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
j(*objs) Показать исходный код
# File ext/json/lib/json/common.rb, line 444
def j(*objs)
  objs.each do |obj|
    puts JSON::generate(obj, :allow_nan => true, :max_nesting => false)
  end
  nil
end

Выводит objs в стандартный вывод (STDOUT) в виде строк JSON в краткой форме, то есть в одну строку.

jj(*objs) Показать исходный код
# File ext/json/lib/json/common.rb, line 453
def jj(*objs)
  objs.each do |obj|
    puts JSON::pretty_generate(obj, :allow_nan => true, :max_nesting => false)
  end
  nil
end

Выводит objs в стандартный вывод (STDOUT) в виде строк JSON в красивом формате с отступами и на нескольких строках.

open(path [, mode [, perm]] [, opt]) → io or nil Показать исходный код
open(path [, mode [, perm]] [, opt]) {|io| block } → obj
static VALUE
rb_f_open(int argc, VALUE *argv)
{
    ID to_open = 0;
    int redirect = FALSE;

    if (argc >= 1) {
        CONST_ID(to_open, "to_open");
        if (rb_respond_to(argv[0], to_open)) {
            redirect = TRUE;
        }
        else {
            VALUE tmp = argv[0];
            FilePathValue(tmp);
            if (NIL_P(tmp)) {
                redirect = TRUE;
            }
            else {
                VALUE cmd = check_pipe_command(tmp);
                if (!NIL_P(cmd)) {
                    argv[0] = cmd;
                    return rb_io_s_popen(argc, argv, rb_cIO);
                }
            }
        }
    }
    if (redirect) {
        VALUE io = rb_funcall2(argv[0], to_open, argc-1, argv+1);

        if (rb_block_given_p()) {
            return rb_ensure(rb_yield, io, io_close, io);
        }
        return io;
    }
    return rb_io_s_open(argc, argv, rb_cFile);
}

Создает объект IO, подключенный к заданному потоку, файлу или подпроцессу.

Если path не начинается с символа трубы (|), рассматривать его как имя файла для открытия с указанным режимом (по умолчанию «r»).

mode — это либо строка, либо целое число. Если это целое число, оно должно быть побитовым или операторов флагов open(2), таких как File::RDWR или File::EXCL. Если это строка, то это либо «fmode», либо «fmode:ext_enc», либо «fmode:ext_enc:int_enc».

См. документацию IO.new для полного описания директив строки mode.

Если файл создается, его начальные права могут быть установлены с помощью параметра perm. См. File.new и страницы руководства open(2) и chmod(2) для описания прав.

Если указан блок, он будет вызван с объектом IO в качестве параметра, а IO будет автоматически закрыт по завершении блока. Вызов возвращает значение блока.

Если path начинается с символа трубы ("|"), создается подпроцесс, подключенный к вызывающему элементу парой труб. Возвращаемый объект IO может использоваться для записи в стандартный ввод и чтения из стандартного вывода этого подпроцесса.

Если команда после символа трубы — одиночный минус ("|-"), Ruby делает вилку, и этот подпроцесс подключается к родителю. Если команда не "-", подпроцесс выполняет команду.

Когда подпроцесс — Ruby (открыт через "|-"), вызов open возвращает nil. Если с вызовом open связан блок, этот блок будет выполняться дважды — один раз в родительском, а другой — в дочернем процессе.

Параметр блока будет объектом IO в родительском процессе и nil в дочернем. Объект IO родительского процесса будет подключен к $stdin и $stdout дочернего процесса. Подпроцесс будет завершен по завершении блока.

Примеры

Чтение из «testfile»:

open("testfile") do |f|
  print f.gets
end

Производит:

This is line one

Открыть подпроцесс и прочитать его вывод:

cmd = open("|date")
print cmd.gets
cmd.close

Производит:

Wed Apr  9 08:56:31 CDT 2003

Открыть подпроцесс, выполняющий ту же программу Ruby:

f = open("|-", "w+")
if f.nil?
  puts "in Child"
  exit
else
  puts "Got: #{f.gets}"
end

Производит:

Got: in Child

Открыть подпроцесс, используя блок для получения объекта IO:

open "|-" do |f|
  if f then
    # parent process
    puts "Got: #{f.gets}"
  else
    # child process
    puts "in Child"
  end
end

Производит:

Got: in Child
Также алиасируется как: open_uri_original_open, open_uri_original_open
open_uri_original_open(*args)
Псевдоним для: open
require(path) Показать исходный код
# File lib/rubygems/core_ext/kernel_require.rb, line 38
def require path
  RUBYGEMS_ACTIVATION_MONITOR.enter

  path = path.to_path if path.respond_to? :to_path

  spec = Gem.find_unresolved_default_spec(path)
  if spec
    Gem.remove_unresolved_default_spec(spec)
    gem(spec.name)
  end

  # If there are no unresolved deps, then we can use just try
  # normal require handle loading a gem from the rescue below.

  if Gem::Specification.unresolved_deps.empty? then
    RUBYGEMS_ACTIVATION_MONITOR.exit
    return gem_original_require(path)
  end

  # If +path+ is for a gem that has already been loaded, don't
  # bother trying to find it in an unresolved gem, just go straight
  # to normal require.
  #--
  # TODO request access to the C implementation of this to speed up RubyGems

  spec = Gem::Specification.stubs.find { |s|
    s.activated? and s.contains_requirable_file? path
  }

  begin
    RUBYGEMS_ACTIVATION_MONITOR.exit
    return gem_original_require(spec.to_fullpath(path) || path)
  end if spec

  # Attempt to find +path+ in any unresolved gems...

  found_specs = Gem::Specification.find_in_unresolved path

  # If there are no directly unresolved gems, then try and find +path+
  # in any gems that are available via the currently unresolved gems.
  # For example, given:
  #
  #   a => b => c => d
  #
  # If a and b are currently active with c being unresolved and d.rb is
  # requested, then find_in_unresolved_tree will find d.rb in d because
  # it's a dependency of c.
  #
  if found_specs.empty? then
    found_specs = Gem::Specification.find_in_unresolved_tree path

    found_specs.each do |found_spec|
      found_spec.activate
    end

  # We found +path+ directly in an unresolved gem. Now we figure out, of
  # the possible found specs, which one we should activate.
  else

    # Check that all the found specs are just different
    # versions of the same gem
    names = found_specs.map(&:name).uniq

    if names.size > 1 then
      RUBYGEMS_ACTIVATION_MONITOR.exit
      raise Gem::LoadError, "#{path} found in multiple gems: #{names.join ', '}"
    end

    # Ok, now find a gem that has no conflicts, starting
    # at the highest version.
    valid = found_specs.select { |s| s.conflicts.empty? }.last

    unless valid then
      le = Gem::LoadError.new "unable to find a version of '#{names.first}' to activate"
      le.name = names.first
      RUBYGEMS_ACTIVATION_MONITOR.exit
      raise le
    end

    valid.activate
  end

  RUBYGEMS_ACTIVATION_MONITOR.exit
  return gem_original_require(path)
rescue LoadError => load_error
  RUBYGEMS_ACTIVATION_MONITOR.enter

  if load_error.message.start_with?("Could not find") or
      (load_error.message.end_with?(path) and Gem.try_activate(path)) then
    RUBYGEMS_ACTIVATION_MONITOR.exit
    return gem_original_require(path)
  else
    RUBYGEMS_ACTIVATION_MONITOR.exit
  end

  raise load_error
end

Когда требуется RubyGems, #require заменяется собственным, способным загружать библиотеки по требованию.

Когда вы вызываете require 'x', происходит следующее:

  • Если файл можно загрузить из существующего пути загрузки Ruby, он загружается.

  • В противном случае, ищутся установленные библиотеки, содержащие файл, который соответствует. Если он найден в библиотеке 'y', эта библиотека активируется (добавляется в путь загрузки).

Сохраняется стандартная функциональность #require, возвращающая false, если этот файл уже был загружен.

Также алиасируется как: gem_original_require
scanf(format, &b) Показать исходный код
# File lib/scanf.rb, line 773
def scanf(format, &b) #:doc:
  STDIN.scanf(format ,&b)
end

Сканирует стандартный ввод (STDIN) на наличие данных, соответствующих format. Смотрите IO#scanf для получения дополнительной информации.

См. Scanf для получения дополнительной информации о создании строки формата.

Для использования #scanf необходимо выполнить require 'scanf'.

y(*objects) Показать исходный код
# File ext/psych/lib/psych/y.rb, line 4
def y *objects
  puts Psych.dump_stream(*objects)
end

Псевдоним для Psych.dump_stream, предназначенный для использования с IRB.

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

Spec-Zone.ru

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