Spec-Zone.ru › Ruby 3

модуль Kernel

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

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

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

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

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

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 670
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.

pp(*objs) Показать исходный код
# File lib/pp.rb, line 602
def pp(*objs)
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

печатает аргументы в красивой форме.

pp возвращает аргумент(ы).

Также алиас: pp

Общедоступные методы экземпляра

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

Возвращает arg в виде Array.

Сначала пытается вызвать to_ary на arg, затем to_a. Если arg не отвечает на to_ary или to_a, возвращает Array длиной 1, содержащий arg.

Если to_ary или to_a возвращают что-то кроме Array, генерирует исключение TypeError.

Array(["a", "b"])  #=> ["a", "b"]
Array(1..5)        #=> [1, 2, 3, 4, 5]
Array(key: :value) #=> [[:key, :value]]
Array(nil)         #=> []
Array(1)           #=> [1]
BigDecimal(initial, digits, exception: true) Показать исходный код
static VALUE
f_BigDecimal(int argc, VALUE *argv, VALUE self)
{
    ENTER(1);
    Real *pv;
    VALUE obj;

    if (argc > 0 && CLASS_OF(argv[0]) == rb_cBigDecimal) {
        if (argc == 1 || (argc == 2 && RB_TYPE_P(argv[1], T_HASH))) return argv[0];
    }
    obj = TypedData_Wrap_Struct(rb_cBigDecimal, &BigDecimal_data_type, 0);
    pv = VpNewVarArg(argc, argv);
    if (pv == NULL) return Qnil;
    SAVE(pv);
    if (ToValue(pv)) pv = VpCopy(NULL, pv);
    RTYPEDDATA_DATA(obj) = pv;
    RB_OBJ_FREEZE(obj);
    return pv->obj = obj;
}

Создает новый объект BigDecimal.

initial

Начальное значение в виде Integer, Float, Rational, BigDecimal или String.

Если это String, пробелы игнорируются, а нераспознанные символы завершают значение.

digits

Количество значащих цифр в виде Integer. Если опущено или равно 0, количество значащих цифр определяется по начальному значению.

Фактическое количество значащих цифр, используемых в вычислениях, обычно больше указанного числа.

exception

Указывает, следует ли генерировать исключение при неверных аргументах. По умолчанию равно true, если передано false, возвращает nil для неверных.

Исключения

TypeError

Если тип initial не является Integer, Float, Rational или BigDecimal, генерируется это исключение.

TypeError

Если digits не является Integer, генерируется это исключение.

ArgumentError

Если initial является Float, а digits больше Float::DIG + 1, генерируется это исключение.

ArgumentError

Если initial является Float или Rational, а значение digits опущено, генерируется это исключение.

Complex(x[, y], exception: true) → числовое или nil Показать исходный код
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

    if (rb_scan_args(argc, argv, "11:", &a1, &a2, &opts) == 1) {
        a2 = Qundef;
    }
    if (!NIL_P(opts)) {
        raise = rb_opts_exception_p(opts, raise);
    }
    if (argc > 0 && CLASS_OF(a1) == rb_cComplex && a2 == Qundef) {
        return a1;
    }
    return nucomp_convert(rb_cComplex, a1, a2, raise);
}

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

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

Complex(1, nil, exception: false)  #=> nil
Complex('1+2', exception: false)   #=> nil

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

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, exception: true) → число с плавающей точкой или nil Показать исходный код
# File kernel.rb, line 171
def Float(arg, exception: true)
  Primitive.rb_f_float(arg, exception)
end

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

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
Float("123.0_badstring", exception: false)  #=> nil
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, exception: true) → целое число или nil Показать исходный код
static VALUE
rb_f_integer(int argc, VALUE *argv, VALUE obj)
{
    VALUE arg = Qnil, opts = Qnil;
    int base = 0;

    if (argc > 1) {
        int narg = 1;
        VALUE vbase = rb_check_to_int(argv[1]);
        if (!NIL_P(vbase)) {
            base = NUM2INT(vbase);
            narg = 2;
        }
        if (argc > narg) {
            VALUE hash = rb_check_hash_type(argv[argc-1]);
            if (!NIL_P(hash)) {
                opts = rb_extract_keywords(&hash);
                if (!hash) --argc;
            }
        }
    }
    rb_check_arity(argc, 1, 2);
    arg = argv[0];

    return rb_convert_to_integer(arg, base, opts_exception_p(opts));
}

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

Передача nil генерирует TypeError, а передача String, которая не соответствует представлению числа, генерирует ArgumentError. Это поведение можно изменить, передав exception: false, в этом случае не преобразуемое значение вернет nil.

Integer(123.999)    #=> 123
Integer("0x1a")     #=> 26
Integer(Time.new)   #=> 1204973019
Integer("0930", 10) #=> 930
Integer("111", 2)   #=> 7
Integer(" +1_0 ")   #=> 10
Integer(nil)        #=> TypeError: can't convert nil into Integer
Integer("x")        #=> ArgumentError: invalid value for Integer(): "x"

Integer("x", exception: false)        #=> nil
Pathname(path) → путь Показать исходный код
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
    if (CLASS_OF(str) == rb_cPathname)
        return 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, exception: true) → рациональное или nil
Rational(arg, exception: true) → рациональное или nil
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

    if (rb_scan_args(argc, argv, "11:", &a1, &a2, &opts) == 1) {
        a2 = Qundef;
    }
    if (!NIL_P(opts)) {
        raise = rb_opts_exception_p(opts, raise);
    }
    return nurat_convert(rb_cRational, a1, a2, raise);
}

Возвращает x/y или arg в виде Rational.

Rational(2, 3)   #=> (2/3)
Rational(5)      #=> (5/1)
Rational(0.5)    #=> (1/2)
Rational(0.3)    #=> (5404319552844595/18014398509481984)

Rational("2/3")  #=> (2/3)
Rational("0.3")  #=> (3/10)

Rational("10 cents")  #=> ArgumentError
Rational(nil)         #=> TypeError
Rational(1, nil)      #=> TypeError

Rational("10 cents", exception: false)  #=> nil

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

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 как String.

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

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

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

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

__dir__ → строка Показать исходный код
static VALUE
f_current_dirname(VALUE _)
{
    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(VALUE _)
{
    ID fname = prev_frame_func(); /* need *method* ID */

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

Возвращает имя при определении текущего метода как Symbol. Если вызвана вне метода, возвращает 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);
    RFILE(port)->fptr = NULL;
    rb_io_fptr_finalize(fptr);
    rb_gc_force_recycle(port); /* also guards from premature GC */

    return result;
}

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

`date`                   #=> "Wed Apr  9 08:56:30 CDT 2003\n"
`ls testdir`.split[1]    #=> "main.rb"
`echo oops && exit 99`   #=> "oops\n"
$?.exitstatus            #=> 99
abort Показать исходный код
Kernel::abort([msg])
abort([msg])
static VALUE
f_abort(int c, const VALUE *a, VALUE _)
{
    rb_f_abort(c, a);
    UNREACHABLE_RETURN(Qnil);
}

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

at_exit { block } → proc Показать исходный код
static VALUE
rb_f_at_exit(VALUE _)
{
    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;
}

Преобразует block в объект 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(module, filename) → nil Показать исходный код
static VALUE
rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
{
    VALUE klass = rb_class_real(rb_vm_cbase());
    if (!klass) {
        rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
    }
    return rb_mod_autoload(klass, sym, file);
}

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

autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
autoload?(name, inherit=true) → String or nil Показать исходный код
static VALUE
rb_f_autoload_p(int argc, VALUE *argv, VALUE obj)
{
    /* 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(argc, argv, klass);
}

Возвращает filename для загрузки, если name зарегистрирован как autoload.

autoload(:B, "b")
autoload?(:B)            #=> "b"
binding → a_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 or false Показать исходный код
static VALUE
rb_f_block_given_p(VALUE _)
{
    rb_execution_context_t *ec = GET_EC();
    rb_control_frame_t *cfp = ec->cfp;
    cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));

    if (cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE) {
        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 для получения дополнительной информации. Также см. Kernel#throw для альтернативного механизма разматывания стека вызовов.

caller(start=1, length=nil) → array or nil Показать исходный код
caller(range) → array or nil
static VALUE
rb_f_caller(int argc, VALUE *argv, VALUE _)
{
    return ec_backtrace_to_ary(GET_EC(), 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) → array or nil Показать исходный код
caller_locations(range) → array or nil
static VALUE
rb_f_caller_locations(int argc, VALUE *argv, VALUE _)
{
    return ec_backtrace_to_ary(GET_EC(), 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 self)
{
    VALUE tag = rb_check_arity(argc, 0, 1) ? argv[0] : rb_obj_alloc(rb_cObject);
    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 _)
{
    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(VALUE _)
{
    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.

class → class Показать исходный код
# File kernel.rb, line 18
def class
  Primitive.attr! 'inline'
  Primitive.cexpr! 'rb_obj_class(self)'
end

Возвращает класс obj. Этот метод всегда должен вызываться с явным получателем, так как class также является служебным словом в Ruby.

1.class      #=> Integer
self.class   #=> Object
clone(freeze: nil) → an_object Показать исходный код
# File kernel.rb, line 47
def clone(freeze: nil)
  Primitive.rb_obj_clone2(freeze)
end

Создаёт неглубокую копию obj — копируются переменные экземпляра obj, но не объекты, на которые они ссылаются. clone копирует состояние замороженного значения obj, если не указан ключевой аргумент :freeze со значением false или true. См. также обсуждение в Object#dup.

class Klass
   attr_accessor :str
end
s1 = Klass.new      #=> #<Klass:0x401b3a38>
s1.str = "Hello"    #=> "Hello"
s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
s2.str[1,4] = "i"   #=> "i"
s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"

Этот метод может иметь специфическое поведение для класса. В этом случае это поведение будет описано в методе #initialize_copy класса.

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;

    if (NIL_P(scope))
        return eval_string_with_cref(self, src, NULL, file, line);
    else
        return eval_string_with_scope(scope, src, 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"
END_OF_DOCUMENT_MARKER
exec([env,] command... [,options]) Показать исходный код
static VALUE
f_exec(int c, const VALUE *a, VALUE _)
{
    rb_f_exec(c, a);
    UNREACHABLE_RETURN(Qnil);
}

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

exec(commandline)

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

exec(cmdname, arg1, ...)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Это поведение изменяется заданными параметрами env и options. Подробнее см. ::spawn.

Если команда не выполняется (обычно Errno::ENOENT, когда она не найдена), генерируется исключение SystemCallError.

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

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

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

В случае необходимости создать дочерний процесс, используйте ::spawn или Kernel#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)
static VALUE
f_exit(int c, const VALUE *a, VALUE _)
{
    rb_f_exit(c, a);
    UNREACHABLE_RETURN(Qnil);
}

Инициирует завершение скрипта 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)
{
    int istatus;

    if (rb_check_arity(argc, 0, 1) == 1) {
        istatus = exit_status_code(argv[0]);
    }
    else {
        istatus = EXIT_FAILURE;
    }
    _exit(istatus);

    UNREACHABLE_RETURN(Qnil);
}

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

Process.exit!(true)
fail
fail(string, cause: $!)
fail(exception [, string [, array]], cause: $!)

Без аргументов, генерирует исключение в $! или генерирует RuntimeError, если $! равно nil. С одним аргументом String, генерирует RuntimeError с строкой в качестве сообщения. В противном случае, первый параметр должен быть классом Exception (или другим объектом, возвращающим объект Exception при отправке сообщения exception). Необязательный второй параметр задаёт сообщение, связанное с исключением (доступно через Exception#message), а третий — массив информации обратного вызова (доступно через Exception#backtrace). Причина сгенерированного исключения (доступно через Exception#cause) автоматически устанавливается в «текущее» исключение ($!), если таковое есть. Альтернативное значение, объект Exception или nil, может быть указано с помощью аргумента :cause.

Исключения перехватываются блоком rescue блоков begin...end.

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
Псевдоним для: raise
fork [{ block }] → integer or nil Показать исходный код
fork [{ block }] → integer or nil
static VALUE
rb_f_fork(VALUE obj)
{
    rb_pid_t pid;

    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(format_string [, arguments...] ) → string

Возвращает строку, полученную в результате применения 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 поддерживает ссылку по имени. Стиль %<name>s использует стиль форматирования, а стиль %{name} — нет.

Примеры:

sprintf("%<foo>d : %<bar>f", { :foo => 1, :bar => 2 })
  #=> 1 : 2.000000
sprintf("%{foo}f", { :foo => 1 })
  # => "1f"
Псевдоним для: sprintf
frozen? → true or false Показать исходный код
# File kernel.rb, line 67
def frozen?
  Primitive.attr! 'inline'
  Primitive.cexpr! 'rb_obj_frozen_p(self)'
end

Возвращает статус замораживания obj.

a = [ "a", "b", "c" ]
a.freeze    #=> ["a", "b", "c"]
a.frozen?   #=> true
Псевдоним для: require
gets(sep=$/ [, getline_args]) → строка или nil Показать исходный код
gets(limit [, getline_args]) → строка или nil
gets(sep, limit [, getline_args]) → строка или nil
static VALUE
rb_f_gets(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_gets(argc, argv, argf);
    }
    return rb_funcallv(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 → массив Показать исходный код
static VALUE
f_global_variables(VALUE _)
{
    return rb_f_global_variables();
}

Возвращает массив имён глобальных переменных. Это включает специальные глобальные переменные-регулярные выражения, такие как $~ и $+, но не включает пронумерованные глобальные переменные-регулярные выражения ($1, $2, и т.д.).

global_variables.grep /std/   #=> [:$stdin, :$stdout, :$stderr]
gsub(pattern, replacement) → $_ Показать исходный код
gsub(pattern) {|...| block } → $_
static VALUE
rb_f_gsub(int argc, VALUE *argv, VALUE _)
{
    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 Показать исходный код
static VALUE
rb_f_iterator_p(VALUE self)
{
    rb_warn_deprecated("iterator?", "block_given?");
    return rb_f_block_given_p(self);
}

Устарело. Используйте block_given? вместо этого.

lambda { |...| block } → a_proc Показать исходный код
static VALUE
f_lambda(VALUE _)
{
    f_lambda_warn();
    return rb_block_lambda();
}

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

load(filename, wrap=false) → true Показать исходный код
static VALUE
rb_f_load(int argc, VALUE *argv, VALUE _)
{
    VALUE fname, wrap, path, orig_fname;

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

    orig_fname = rb_get_path_check_to_string(fname);
    fname = rb_str_encode_ospath(orig_fname);
    RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(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));

    RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));

    return Qtrue;
}

Загружает и выполняет Ruby-программу из файла filename.

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

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

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

Если файла не существует при попытке загрузки, будет вызвано исключение LoadError.

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

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

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

            if (vm_collect_local_variables_in_heap(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 { block } Показать исходный код
loop → перечислитель
static VALUE
rb_f_loop(VALUE self)
{
    RETURN_SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size);
    return rb_rescue2(loop_i, (VALUE)0, loop_stop, (VALUE)0, rb_eStopIteration, (VALUE)0);
}

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

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

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

Исключение StopIteration в блоке прерывает цикл. В этом случае loop возвращает значение «результата», сохранённое в исключении.

enum = Enumerator.new { |y|
  y << "one"
  y << "two"
  :ok
}

result = loop {
  puts enum.next
} #=> :ok
open(path [, mode [, perm]] [, opt]) → io или nil Показать исходный код
open(path [, mode [, perm]] [, opt]) {|io| block } → obj
static VALUE
rb_f_open(int argc, VALUE *argv, VALUE _)
{
    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_funcallv_kw(argv[0], to_open, argc-1, argv+1, RB_PASS_CALLED_KEYWORDS);

        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
p(obj) → obj Показать исходный код
p(obj1, obj2, ...) → [obj, ...]
p() → nil
static VALUE
rb_f_p(int argc, VALUE *argv, VALUE self)
{
    int i;
    for (i=0; i<argc; i++) {
        VALUE inspected = rb_obj_as_string(rb_inspect(argv[i]));
        rb_uninterruptible(rb_p_write, inspected);
    }
    return rb_p_result(argc, argv);
}

Для каждого объекта непосредственно выводит obj.inspect, после чего — символ новой строки в стандартный вывод программы.

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

выводит:

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

Возвращает красивое представление объекта в виде строки.

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

require 'pp'

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

print(obj, ...) → nil Показать исходный код
static VALUE
rb_f_print(int argc, const VALUE *argv, VALUE _)
{
    rb_io_print(argc, argv, rb_ractor_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 _)
{
    VALUE out;

    if (argc == 0) return Qnil;
    if (RB_TYPE_P(argv[0], T_STRING)) {
        out = rb_ractor_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 Показать исходный код
static VALUE
f_proc(VALUE _)
{
    return proc_new(rb_cProc, FALSE, TRUE);
}

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

putc(int) → int Показать исходный код
static VALUE
rb_f_putc(VALUE recv, VALUE ch)
{
    VALUE r_stdout = rb_ractor_stdout();
    if (recv == r_stdout) {
        return rb_io_putc(recv, ch);
    }
    return rb_funcallv(r_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)
{
    VALUE r_stdout = rb_ractor_stdout();
    if (recv == r_stdout) {
        return rb_io_puts(argc, argv, recv);
    }
    return rb_funcallv(r_stdout, rb_intern("puts"), argc, argv);
}

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

$stdout.puts(obj, ...)
raise Показать исходный код
raise(string, cause: $!)
raise(exception [, string [, array]], cause: $!)
static VALUE
f_raise(int c, VALUE *v, VALUE _)
{
    return rb_f_raise(c, v);
}

Без аргументов, поднимает исключение в $! или поднимает RuntimeError, если $! равно nil. С одним аргументом-строкой, поднимает RuntimeError с этой строкой как сообщение. В противном случае, первый параметр должен быть классом Exception (или другим объектом, возвращающим объект Exception при получении сообщения exception). Необязательный второй параметр задаёт сообщение, связанное с исключением (доступное через Exception#message), а третий параметр — массив информации о вызове (доступный через Exception#backtrace). Причина возникновения исключения (доступная через Exception#cause) автоматически устанавливается в «текущее» исключение ($!), если таковое имеется. Альтернативное значение, либо объект Exception, либо nil, может быть указано с помощью аргумента :cause.

Исключения перехватываются в rescue блоков begin...end.

raise "Failed to create socket"
raise ArgumentError, "No parameters", caller
Также алиасировано как: fail
rand(max=0) → number Показать исходный код
static VALUE
rb_f_rand(int argc, VALUE *argv, VALUE obj)
{
    VALUE vmax;
    rb_random_t *rnd = rand_start(default_rand());

    if (rb_check_arity(argc, 0, 1) && !NIL_P(vmax = argv[0])) {
        VALUE v = rand_range(obj, rnd, vmax);
        if (v != Qfalse) return v;
        vmax = rb_to_int(vmax);
        if (vmax != INT2FIX(0)) {
            v = rand_int(obj, rnd, vmax, 0);
            if (!NIL_P(v)) return v;
        }
    }
    return DBL2NUM(random_real(obj, rnd, TRUE));
}

Если вызвана без аргумента или если 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 является Range, 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

Kernel.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_funcallv(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_funcallv(argf, rb_intern("readlines"), argc, argv);
}

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

require(name) → true or false Показать исходный код
VALUE
rb_f_require(VALUE obj, VALUE fname)
{
    return rb_require_string(fname);
}

Загружает заданный name, возвращая true при успехе и false если модуль уже загружен.

Если имя файла не разрешается до абсолютного пути и не начинается с './' или '../', файл будет искаться в каталогах библиотек, перечисленных в $LOAD_PATH ($:). Если имя файла начинается с './' или '../', разрешение основывается на Dir.pwd.

Если имя файла имеет расширение “.rb”, оно загружается как исходный файл; если расширение ".so", ".o", или ".dll", или стандартное расширение динамической библиотеки текущей платформы, Ruby загружает динамическую библиотеку как расширение Ruby. В противном случае, Ruby пытается добавить ".rb", ".so" и т.д. к имени до тех пор, пока не найдёт. Если файл не найден, будет выброшено исключение LoadError.

Для расширений Ruby имя файла может использовать любое расширение динамической библиотеки. Например, в Linux расширение сокета — «socket.so», и require 'socket.dll' загрузит расширение сокета.

Абсолютный путь загруженного файла добавляется в $LOADED_FEATURES ($"). Файл не будет загружен повторно, если его путь уже есть в $". Например, require 'a'; require './a' не загрузит a.rb повторно.

require "my-library.rb"
require "db-driver"

Любые константы или глобальные переменные в загруженном исходном файле будут доступны в глобальном пространстве имен вызывающей программы. Однако локальные переменные не будут перенесены в среду загрузки.

Также алиасировано как: gem_original_require
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_string(rb_file_absolute_path(fname, base));
}

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 может вызвать системный вызов записи, и он может заблокироваться. В такой ситуации OpenSSL::SSL::SSLSocket#read_nonblock возбуждает IO::WaitWritable вместо блокировки. Поэтому вызывающая процедура должна ждать готовности к записи, как в примере выше.

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

Наконец, разработчики ядра 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]) → integer Показать исходный код
static VALUE
rb_f_sleep(int argc, VALUE *argv, VALUE _)
{
    time_t beg = time(0);
    VALUE scheduler = rb_scheduler_current();

    if (scheduler != Qnil) {
        rb_scheduler_kernel_sleepv(scheduler, argc, argv);
    }
    else {
        if (argc == 0) {
            rb_thread_sleep_forever();
        }
        else {
            rb_check_arity(argc, 0, 1);
            rb_thread_wait_for(rb_time_interval(argv[0]));
        }
    }

    time_t end = time(0) - beg;

    return TIMET2NUM(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, VALUE _)
{
    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, FALSE);
    eargp = rb_execarg_get(execarg_obj);
    fail_str = eargp->use_shell ? eargp->invoke.sh.shell_script : eargp->invoke.cmd.command_name;

    pid = rb_execarg_spawn(execarg_obj, errmsg, sizeof(errmsg));

    if (pid == -1) {
        int err = errno;
        rb_exec_fail(eargp, err, errmsg);
        RB_GC_GUARD(execarg_obj);
        rb_syserr_fail_str(err, fail_str);
    }
#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

Этот метод похож на Kernel#system, но не ожидает завершения команды.

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

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

env: hash
  name => val : set the environment variable
  name => nil : unset the environment variable

  the keys and the values except for +nil+ must be strings.
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 the 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 => false  : inherit
  current directory:
    :chdir => str

Форма cmdname, arg1, ... не использует оболочку. Однако на разных ОС предоставляются разные встроенные команды. Примером является +'echo'+, который является встроенной командой в Windows, но обычной программой в Linux и Mac OS X. Это означает, что Process.spawn 'echo', '%Path%' выведет содержимое переменной окружения %Path% в Windows, но Process.spawn 'echo', '$PATH' отобразит буквально $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, нулём, положительным целым числом или nil. true и ноль заставляют процесс стать лидером новой группы процессов. Положительное целое число заставляет процесс присоединиться к заданной группе процессов. Значение по умолчанию, nil, заставляет процесс остаться в той же группе процессов.

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.

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

# 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 по умолчанию false для 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 указывается в качестве значения хеша для закрытия fd индивидуально.

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 Показать исходный код
static VALUE
f_sprintf(int c, const VALUE *v, VALUE _)
{
    return rb_f_sprintf(c, v);
}

Возвращает строку, полученную в результате применения 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 поддерживает ссылку по имени. Стиль %<name>s использует стиль форматирования, но стиль %{name} - нет.

Примеры:

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

    if (rb_check_arity(argc, 0, 1) == 0) {
        seed = random_seed(obj);
    }
    else {
        seed = rb_to_int(argv[0]);
    }
    old = r->base.seed;
    rand_init(&random_mt_if, &r->base, seed);
    r->base.seed = seed;

    return old;
}

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

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

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

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 _)
{
    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, VALUE _)
{
    VALUE arg[8];
#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_category_warning(RB_WARN_CATEGORY_DEPRECATED,
            "We plan to remove a syscall function at future release. DL(Fiddle) provides safer alternative.");
    }

    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;
    }

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

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

Аргументы для функции могут следовать за num. Они должны быть либо String объектами, либо Integer объектами. String объект передается как указатель на байтовую последовательность. Integer объект передается как целое число, размер которого в битах совпадает с размером указателя. Можно передать до девяти параметров.

Функция, идентифицированная по 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], exception: false) → true, false or nil Показать исходный код
static VALUE
rb_f_system(int argc, VALUE *argv, VALUE _)
{
    /*
     * n.b. using alloca for now to simplify future Thread::Light code
     * when we need to use malloc for non-native Fiber
     */
    struct waitpid_state *w = alloca(sizeof(struct waitpid_state));
    rb_pid_t pid; /* may be different from waitpid_state.pid on exec failure */
    VALUE execarg_obj;
    struct rb_execarg *eargp;
    int exec_errnum;

    execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
    eargp = rb_execarg_get(execarg_obj);
    w->ec = GET_EC();
    waitpid_state_init(w, 0, 0);
    eargp->waitpid_state = w;
    pid = rb_execarg_spawn(execarg_obj, 0, 0);
    exec_errnum = pid < 0 ? errno : 0;

#if defined(HAVE_WORKING_FORK) || defined(HAVE_SPAWNV)
    if (w->pid > 0) {
        /* `pid' (not w->pid) may be < 0 here if execve failed in child */
        if (WAITPID_USE_SIGCHLD) {
            rb_ensure(waitpid_sleep, (VALUE)w, waitpid_cleanup, (VALUE)w);
        }
        else {
            waitpid_no_SIGCHLD(w);
        }
        rb_last_status_set(w->status, w->ret);
    }
#endif
    if (w->pid < 0 /* fork failure */ || pid < 0 /* exec failure */) {
        if (eargp->exception) {
            int err = exec_errnum ? exec_errnum : w->errnum;
            VALUE command = eargp->invoke.sh.shell_script;
            RB_GC_GUARD(execarg_obj);
            rb_syserr_fail_str(err, command);
        }
        else {
            return Qnil;
        }
    }
    if (w->status == EXIT_SUCCESS) return Qtrue;
    if (eargp->exception) {
        VALUE command = eargp->invoke.sh.shell_script;
        VALUE str = rb_str_new_cstr("Command failed with");
        rb_str_cat_cstr(pst_message_status(str, w->status), ": ");
        rb_str_append(str, command);
        RB_GC_GUARD(execarg_obj);
        rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
    }
    else {
        return Qfalse;
    }
}

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

commandline

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

cmdname, arg1, ...

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

[cmdname, argv0], arg1, ...

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

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

Если передан аргумент exception: true, метод вызывает исключение вместо возврата false или nil.

Аргументы обрабатываются так же, как и для Kernel#spawn.

Хэш-аргументы env и options такие же, как у exec и spawn. См. Kernel#spawn для подробностей.

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

выдает:

config.h main.rb
*

Обработка ошибок:

system("cat nonexistent.txt")
# => false
system("catt nonexistent.txt")
# => nil

system("cat nonexistent.txt", exception: true)
# RuntimeError (Command failed with exit 1: cat)
system("catt nonexistent.txt", exception: true)
# Errno::ENOENT (No such file or directory - catt)

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

tap {|x| block } → obj Показать исходный код
# File kernel.rb, line 89
def tap
  yield(self)
  self
end

Передает self в блок, а затем возвращает self. Основная цель этого метода — «подключиться» к цепочке методов, чтобы выполнять операции над промежуточными результатами в цепочке.

(1..10)                  .tap {|x| puts "original: #{x}" }
  .to_a                  .tap {|x| puts "array:    #{x}" }
  .select {|x| x.even? } .tap {|x| puts "evens:    #{x}" }
  .map {|x| x*x }        .tap {|x| puts "squares:  #{x}" }
test(cmd, file1 [, file2] ) → obj Показать исходный код
static VALUE
rb_f_test(int argc, VALUE *argv, VALUE _)
{
    int cmd;

    if (argc == 0) rb_check_arity(argc, 2, 3);
    cmd = NUM2CHR(argv[0]);
    if (cmd == 0) {
        goto unknown;
    }
    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) {
            int e = errno;
            FilePathValue(fname);
            rb_syserr_fail_path(e, 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;
        struct timespec t1, t2;

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

        t1 = stat_mtimespec(&st1);
        t2 = stat_mtimespec(&st2);

        switch (cmd) {
          case '=':
            if (t1.tv_sec == t2.tv_sec && t1.tv_nsec == t2.tv_nsec) return Qtrue;
            return Qfalse;

          case '>':
            if (t1.tv_sec > t2.tv_sec) return Qtrue;
            if (t1.tv_sec == t2.tv_sec && t1.tv_nsec > t2.tv_nsec) return Qtrue;
            return Qfalse;

          case '<':
            if (t1.tv_sec < t2.tv_sec) return Qtrue;
            if (t1.tv_sec == t2.tv_sec && t1.tv_nsec < t2.tv_nsec) return Qtrue;
            return Qfalse;
        }
    }
  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);
    }
    UNREACHABLE_RETURN(Qundef);
}

Использует символ 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
then {|x| block } → an_object Показать исходный код
# File kernel.rb, line 120
def then
  unless Primitive.block_given_p
    return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
  end
  yield(self)
end

Передает self в блок и возвращает результат работы блока.

3.next.then {|x| x**x }.to_s             #=> "256"

Хорошее применение для then - это передача значений в цепочках методов:

require 'open-uri'
require 'json'

construct_url(arguments).
  then {|url| open(url).read }.
  then {|response| JSON.parse(response) }

При вызове без блока метод возвращает Enumerator, что может быть использовано, например, для условного прерывания цепи:

# meets condition, no-op
1.then.detect(&:odd?)            # => 1
# does not meet condition, drop value
2.then.detect(&:odd?)            # => nil
throw(tag [, obj]) Показать исходный код
static VALUE
rb_f_throw(int argc, VALUE *argv, VALUE _)
{
    VALUE tag, value;

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

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

trace_var(symbol, cmd ) → nil Показать исходный код
trace_var(symbol) {|val| block } → nil
static VALUE
f_trace_var(int c, const VALUE *a, VALUE _)
{
    return rb_f_trace_var(c, a);
}

Управляет трассировкой присваиваний глобальным переменным. Параметр 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, VALUE _)
{
    int sig;
    sighandler_t func;
    VALUE cmd;

    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 (rb_obj_is_proc(cmd) &&
        !rb_ractor_main_p() && !rb_ractor_shareable_p(cmd)) {
        cmd = rb_proc_isolate(cmd);
    }

    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 Показать исходный код
static VALUE
f_untrace_var(int c, const VALUE *a, VALUE _)
{
    return rb_f_untrace_var(c, a);
}

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

warn(*msgs, uplevel: nil, category: nil) → nil Показать исходный код
# File warning.rb, line 50
def warn(*msgs, uplevel: nil, category: nil)
  Primitive.rb_warn_m(msgs, uplevel, category)
end

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

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

<em>produces:</em>

  warning 1
  warning 2

Если указан именованный аргумент uplevel, строка будет дополнена информацией о данном фрейме вызывающего объекта в том же формате, что используется функцией C rb_warn.

  # In baz.rb
  def foo
    warn("invalid call to foo", uplevel: 1)
  end

  def bar
    foo
  end

  bar

<em>produces:</em>

  baz.rb:6: warning: invalid call to foo

Если указан именованный аргумент category, передает категорию в Warning.warn. Указанная категория должна быть одной из следующих:

:deprecated

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

:experimental

Используется для экспериментальных функций, которые могут измениться в будущих версиях.

yield_self {|x| block } → an_object Показать исходный код
# File kernel.rb, line 144
def yield_self
  unless Primitive.block_given_p
    return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_obj_size)'
  end
  yield(self)
end

Передает self в блок и возвращает результат работы блока.

"my string".yield_self {|s| s.upcase }   #=> "MY STRING"

Хорошее применение для then - это передача значений в цепочках методов:

require 'open-uri'
require 'json'

construct_url(arguments).
  then {|url| open(url).read }.
  then {|response| JSON.parse(response) }

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

JSON(object, *args) Показать исходный код
# File ext/json/lib/json/common.rb, line 685
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 передаётся в функцию generate/parse соответственно. См. документацию generate и parse.

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 670
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 41
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

  if spec
    if Gem::LOADED_SPECS_MUTEX.owned?
      spec.activate
    else
      Gem::LOADED_SPECS_MUTEX.synchronize { spec.activate }
    end
  end
end

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

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

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

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

Kernel#gem следует вызывать перед любыми операторами require (в противном случае RubyGems может загрузить конфликтную версию библиотеки).

Kernel#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 663
def j(*objs)
  objs.each do |obj|
    puts JSON::generate(obj, :allow_nan => true, :max_nesting => false)
  end
  nil
end

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

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

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

pp(*objs) Показать исходный код
# File lib/pp.rb, line 602
def pp(*objs)
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

выводит аргументы в красивой форме.

pp возвращает аргумент(ы).

Также переименовано как: pp
y(*objects) Показать исходный код
# File ext/psych/lib/psych/y.rb, line 5
def y *objects
  puts Psych.dump_stream(*objects)
end

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

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

Spec-Zone.ru

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