Spec-Zone.ru › Ruby 3.3

модуль Kernel

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

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

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

Что здесь

Модуль Kernel предоставляет методы, полезные для:

  • Преобразования

  • Запросов

  • Выхода

  • Исключений

  • IO

  • Программ

  • Отслеживания

  • Подпроцессов

  • Загрузки

  • Возвращения

  • Случайных значений

  • Другое

Преобразования

  • Array: Возвращает Array на основе заданного аргумента.

  • Complex: Возвращает Complex на основе заданных аргументов.

  • Float: Возвращает Float на основе заданных аргументов.

  • Hash: Возвращает Hash на основе заданного аргумента.

  • Integer: Возвращает Integer на основе заданных аргументов.

  • Rational: Возвращает Rational на основе заданных аргументов.

  • String: Возвращает String на основе заданного аргумента.

Запросы

  • __callee__: Возвращает имя вызываемого метода как символ.

  • __dir__: Возвращает путь к каталогу, из которого вызывается текущий метод.

  • __method__: Возвращает имя текущего метода как символ.

  • autoload?: Возвращает файл для загрузки, когда модуль задан.

  • binding: Возвращает Binding для контекста в момент вызова.

  • block_given?: Возвращает true, если блоку был передан вызывающий метод.

  • caller: Возвращает текущую стек вызовов как массив строк.

  • caller_locations: Возвращает текущую стек вызовов как массив объектов Thread::Backtrace::Location.

  • class: Возвращает класс self.

  • frozen?: Возвращает, заморожен ли self.

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

  • local_variables: Возвращает массив локальных переменных как символы.

  • test: Выполняет заданные тесты для заданного файла или пары файлов.

Выход

  • abort: Выходит из текущего процесса после вывода заданных аргументов.

  • at_exit: Выполняет заданный блок при завершении процесса.

  • exit: Выходит из текущего процесса после вызова всех зарегистрированных at_exit обработчиков.

  • exit!: Выходит из текущего процесса без вызова зарегистрированных at_exit обработчиков.

Исключения

  • catch: Выполняет заданный блок, возможно перехватывая брошенный объект.

  • raise (алиас fail): Поднимает исключение на основе заданных аргументов.

  • throw: Возвращает из активного блока catch, ожидающего заданный тег.

IO

  • ::pp: Выводит заданные объекты в красивом формате.

  • gets: Возвращает и присваивает $_ следующую строку из текущего ввода.

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

  • p: Выводит инспекцию заданных объектов в стандартный вывод.

  • print: Выводит заданные объекты в стандартный вывод без новой строки.

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

  • putc: Эквивалентно <tt.$stdout.putc(object)</tt> для заданного объекта.

  • puts: Эквивалентно $stdout.puts(*objects) для заданных объектов.

  • readline: Похоже на gets, но вызывает исключение в конце файла.

  • readlines: Возвращает массив оставшихся строк из текущего ввода.

  • select: То же, что и IO.select.

Программы

  • lambda: Возвращает лямбда-программу для заданного блока.

  • proc: Возвращает новую Proc; эквивалентно Proc.new.

Отслеживание

  • set_trace_func: Устанавливает заданную программу в качестве обработчика для отслеживания или отключает отслеживание, если задано nil.

  • trace_var: Начинает отслеживание присваиваний заданной глобальной переменной.

  • untrace_var: Отключает отслеживание присваиваний заданной глобальной переменной.

Подпроцессы

  • `команда`: Возвращает стандартный вывод выполнения command в подоболочке.

  • exec: Заменяет текущий процесс новым процессом.

  • fork: Создает вилку текущего процесса в два процесса.

  • spawn: Выполняет заданную команду и возвращает ее pid без ожидания завершения.

  • system: Выполняет заданную команду в подоболочке.

Загрузка

  • autoload: Регистрирует заданный файл для загрузки, когда константа впервые ссылается на неё.

  • load: Загружает заданный Ruby файл.

  • require: Загружает заданный Ruby файл, если он ещё не загружен.

  • require_relative: Загружает путь к Ruby файлу относительно файла вызова, если он ещё не загружен.

Возвращения

  • tap: Возвращает self заданному блоку; возвращает self.

  • then (алиас yield_self): Возвращает self к блоку и возвращает результат блока.

Случайные значения

  • rand: Возвращает псевдослучайное число с плавающей точкой строго между 0,0 и 1,0.

  • srand: Инициализирует генератор псевдослучайных чисел заданным числом.

Другое

  • eval: Вычисляет заданную строку как код Ruby.

  • loop: Повторяет выполнение заданного блока.

  • sleep: Приостанавливает текущую нить на заданное количество секунд.

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

  • syscall: Выполняет системный вызов операционной системы.

  • trap: Определяет обработку системных сигналов.

  • warn: Выдает предупреждение на основе заданных сообщений и параметров.

Методы открытого класса

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 842
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, который может быть строкой URI или существующим объектом URI:

# Returns a new URI.
uri = URI('http://github.com/ruby/ruby')
# => #<URI::HTTP http://github.com/ruby/ruby>
# Returns the given URI.
URI(uri)
# => #<URI::HTTP http://github.com/ruby/ruby>
pp(*objs) Показать исходный код
# File lib/pp.rb, line 644
def pp(*objs)
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

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

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

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

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

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

Возвращает массив, преобразованный из object.

Попытка преобразовать object в массив с использованием to_ary в первую очередь и to_a во вторую:

Array([0, 1, 2])        # => [0, 1, 2]
Array({foo: 0, bar: 1}) # => [[:foo, 0], [:bar, 1]]
Array(0..4)             # => [0, 1, 2, 3, 4]

Возвращает object в массиве, [object], если object не может быть преобразован:

Array(:foo)             # => [:foo]
BigDecimal(value, exception: true) → bigdecimal Показать исходный код
BigDecimal(value, ndigits, exception: true) → bigdecimal
static VALUE
f_BigDecimal(int argc, VALUE *argv, VALUE self)
{
    VALUE val, digs_v, opts = Qnil;
    argc = rb_scan_args(argc, argv, "11:", &val, &digs_v, &opts);
    int exception = opts_exception_p(opts);

    size_t digs = SIZE_MAX; /* this means digs is omitted */
    if (argc > 1) {
        digs_v = rb_to_int(digs_v);
        if (FIXNUM_P(digs_v)) {
            long n = FIX2LONG(digs_v);
            if (n < 0)
                goto negative_digs;
            digs = (size_t)n;
        }
        else {
            if (RBIGNUM_NEGATIVE_P(digs_v)) {
              negative_digs:
                if (!exception)
                    return Qnil;
                rb_raise(rb_eArgError, "negative precision");
            }
            digs = NUM2SIZET(digs_v);
        }
    }

    return rb_convert_to_BigDecimal(val, digs, exception);
}

Возвращает BigDecimal, преобразованный из value с точностью до ndigits десятичных знаков.

Когда ndigits меньше, чем количество значащих цифр в значении, результат округляется до этого числа знаков в соответствии с текущим режимом округления; см. BigDecimal.mode.

Когда ndigits равно 0, количество цифр для правильного представления числа с плавающей запятой определяется автоматически.

Возвращает value, преобразованный в BigDecimal, в зависимости от типа value:

  • Integer, Float, Rational, Complex или BigDecimal: преобразуются непосредственно:

    # Integer, Complex, or BigDecimal value does not require ndigits; ignored if given.
    BigDecimal(2)                     # => 0.2e1
    BigDecimal(Complex(2, 0))         # => 0.2e1
    BigDecimal(BigDecimal(2))         # => 0.2e1
    # Float or Rational value requires ndigits.
    BigDecimal(2.0, 0)                # => 0.2e1
    BigDecimal(Rational(2, 1), 0)     # => 0.2e1
    
  • Строка: преобразуется путём разбора, если она содержит целое или число с плавающей запятой; ведущие и хвостовые пробелы игнорируются:

    # String does not require ndigits; ignored if given.
    BigDecimal('2')     # => 0.2e1
    BigDecimal('2.0')   # => 0.2e1
    BigDecimal('0.2e1') # => 0.2e1
    BigDecimal(' 2.0 ') # => 0.2e1
    
  • Другой тип, отвечающий на метод :to_str: сначала преобразуется в строку, а затем в BigDecimal, как указано выше.

  • Другой тип:

    • Вызывает исключение, если ключевой аргумент exception равен true.

    • Возвращает nil , если ключевой аргумент exception равен false.

Вызывает исключение, если value оценивается как Float, а digits больше, чем Float::DIG + 1.

Complex(real, imag = 0, exception: true) → complex или nil Показать исходный код
Complex(s, exception: true) → complex или 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 && UNDEF_P(a2)) {
        return a1;
    }
    return nucomp_convert(rb_cComplex, a1, a2, raise);
}

Возвращает новый объект Complex, если аргументы допустимы; в противном случае вызывает исключение, если exception равно true; в противном случае возвращает nil.

С аргументами Numeric real и imag, возвращает Complex.rect(real, imag), если аргументы допустимы.

С аргументом-строкой s, возвращает новый объект Complex, если аргумент допустим; строка может содержать:

  • Одну или две числовые подстроки, каждая из которых определяет значение Complex, Float, Integer, Numeric или Rational, определяющие прямоугольные координаты:

    • Разделенные знаком вещественная и мнимая числовые подстроки (с заключительным символом 'i'):

      Complex('1+2i')  # => (1+2i)
      Complex('+1+2i') # => (1+2i)
      Complex('+1-2i') # => (1-2i)
      Complex('-1+2i') # => (-1+2i)
      Complex('-1-2i') # => (-1-2i)
      
    • Только вещественная числовая строка (без заключительного символа 'i'):

      Complex('1')  # => (1+0i)
      Complex('+1') # => (1+0i)
      Complex('-1') # => (-1+0i)
      
    • Только мнимая числовая строка (с заключительным символом 'i'):

      Complex('1i')  # => (0+1i)
      Complex('+1i') # => (0+1i)
      Complex('-1i') # => (0-1i)
      
  • Разделенные знаком «@» вещественная и мнимая рациональные подстроки, каждая из которых определяет значение Rational, определяющие полярные координаты:

    Complex('1/2@3/4')   # => (0.36584443443691045+0.34081938001166706i)
    Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i)
    Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i)
    Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i)
    Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i)
    
Float(arg, exception: true) → float или nil Показать исходный код
# File kernel.rb, line 212
def Float(arg, exception: true)
  if Primitive.mandatory_only?
    Primitive.rb_f_float1(arg)
  else
    Primitive.rb_f_float(arg, exception)
  end
end

Возвращает arg, преобразованный в float. Типы 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(object) → object или new_hash Показать исходный код
static VALUE
rb_f_hash(VALUE obj, VALUE arg)
{
    return rb_Hash(arg);
}

Возвращает хэш, преобразованный из object.

  • Если object является:

    • Хэшем, возвращает object.

    • Пустым массивом или nil, возвращает пустой хэш.

  • В противном случае, если object.to_hash возвращает хэш, возвращает этот хэш.

  • В противном случае возвращает TypeError.

Примеры:

Hash({foo: 0, bar: 1}) # => {:foo=>0, :bar=>1}
Hash(nil)              # => {}
Hash([])               # => {}
Integer(object, base = 0, exception: true) → integer или nil Показать исходный код
# File kernel.rb, line 305
def Integer(arg, base = 0, exception: true)
  if Primitive.mandatory_only?
    Primitive.rb_f_integer1(arg)
  else
    Primitive.rb_f_integer(arg, base, exception);
  end
end

Возвращает целое число, преобразованное из object.

Попытка преобразовать object в целое число с использованием to_int в первую очередь и to_i во вторую; см. ниже для исключений.

С ненулевым base, object должно быть строкой или преобразуемым в строку.

числовые объекты

С целочисленным аргументом object заданным, возвращает object:

Integer(1)                # => 1
Integer(-1)               # => -1

С плавающей точкой аргументом object заданным, возвращает object, усечённый до целого числа:

Integer(1.9)              # => 1  # Rounds toward zero.
Integer(-1.9)             # => -1 # Rounds toward zero.

строковые объекты

С аргументом-строкой object и нулевым base заданным, возвращает object преобразованное в целое число в основании 10:

Integer('100')    # => 100
Integer('-100')   # => -100

С base нулём, строка object может содержать ведущие символы для указания фактического основания (индикатор основания):

Integer('0100')  # => 64  # Leading '0' specifies base 8.
Integer('0b100') # => 4   # Leading '0b', specifies base 2.
Integer('0x100') # => 256 # Leading '0x' specifies base 16.

С положительным base (в диапазоне от 2 до 36) заданным, возвращает object преобразованное в целое число в указанном основании:

Integer('100', 2)   # => 4
Integer('100', 8)   # => 64
Integer('-100', 16) # => -256

С отрицательным base (в диапазоне от -36 до -2) заданным, возвращает object преобразованное в целое число в индикаторе основания, если он существует, или -base:

Integer('0x100', -2)   # => 256
Integer('100', -2)     # => 4
Integer('0b100', -8)   # => 4
Integer('100', -8)     # => 64
Integer('0o100', -10)  # => 64
Integer('100', -10)    # => 100

base -1 равно -10 случаю.

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

Integer(' 100 ')      # => 100
Integer('-1_0_0', 16) # => -256

другие классы

Примеры с object различных других классов:

Integer(Rational(9, 10)) # => 0  # Rounds toward zero.
Integer(Complex(2, 0))   # => 2  # Imaginary part must be zero.
Integer(Time.now)        # => 1650974042

ключевые слова

С необязательным ключевым аргументом exception заданным как true (по умолчанию):

  • Вызывает TypeError, если object не отвечает на to_int или to_i.

  • Вызывает TypeError, если object равно nil.

  • Вызывает ArgumentError, если object является недопустимой строкой.

С exception заданным как false, исключение любого типа подавляется, и возвращается nil.

Pathname(path) → pathname Показать исходный код
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.

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

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

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

Rational(x, y, exception: true) → rational or nil Показать исходный код
Rational(arg, exception: true) → rational or 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);
}

Возвращает рациональное число или 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(object) → object or new_string Показать исходный код
static VALUE
rb_f_string(VALUE obj, VALUE arg)
{
    return rb_String(arg);
}

Возвращает строку, преобразованную из object.

Попытка преобразовать object в строку с использованием to_str в первую очередь, и to_s во вторую:

String([0, 1, 2])        # => "[0, 1, 2]"
String(0..5)             # => "0..5"
String({foo: 0, bar: 1}) # => "{:foo=>0, :bar=>1}"

Вызывает TypeError если object не может быть преобразовано в строку.

__callee__ → symbol Показать исходный код
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__ → string Показать исходный код
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__ → symbol Показать исходный код
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.

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

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

    GetOpenFile(port, fptr);
    result = read_all(fptr, remain_size(fptr), Qnil);
    rb_io_close(port);
    rb_io_fptr_cleanup_all(fptr);
    RB_GC_GUARD(port);

    return result;
}

Возвращает вывод $stdout от выполнения command в подоболочке; устанавливает глобальную переменную $? в состояние процесса.

Этот метод может иметь потенциальные уязвимости в случае использования ненадёжных входных данных; см. Инъекция команд.

Примеры:

$ `date`                 # => "Wed Apr  9 08:56:30 CDT 2003\n"
$ `echo oops && exit 99` # => "oops\n"
$ $?                     # => #<Process::Status: pid 17088 exit 99>
$ $?.status              # => 99>

Встроенный синтаксис %x{...} использует этот метод.

abort Показать исходный код
abort(msg = nil)
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(const, 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);
}
Registers _filename_ to be loaded (using Kernel::require)
the first time that _const_ (which may be a String or
a symbol) is accessed.

   autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")

Если const определен как autoload, имя файла для загрузки заменяется на filename. Если const определен, но не как autoload, ничего не происходит.

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, описывающий связи переменных и методов в момент вызова. Этот объект может использоваться при вызове Binding#eval для выполнения команды в этой среде или извлечения локальных переменных.

class User
  def initialize(name, position)
    @name = name
    @position = position
  end

  def get_binding
    binding
  end
end

user = User.new('Joan', 'manager')
template = '{name: @name, position: @position}'

# evaluate template in context of the object
eval(template, user.get_binding)
#=> {:name=>"Joan", :position=>"manager"}

Binding#local_variable_get может использоваться для доступа к переменным, чьи имена являются зарезервированными ключевыми словами Ruby:

# This is valid parameter declaration, but `if` parameter can't
# be accessed by name, because it is a reserved word.
def validate(field, validation, if: nil)
  condition = binding.local_variable_get('if')
  return unless condition

  # ...Some implementation ...
end

validate(:name, :empty?, if: false) # skips validation
validate(:name, :empty?, if: true) # performs validation
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));

    return RBOOL(cfp != NULL && VM_CF_BLOCK_HANDLER(cfp) != VM_BLOCK_HANDLER_NONE);
}

Возвращает 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 Show source
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 → $_ Show source
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 → $_ Show source
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 Show source
# File kernel.rb, line 18
def class
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_obj_class(self)'
end

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

1.class      #=> Integer
self.class   #=> Object
clone(freeze: nil) → an_object Show source
# 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 Show source
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"
exec([env, ] command_line, options = {}) Show source
exec([env, ] exe_path, *args, options = {})
static VALUE
f_exec(int c, const VALUE *a, VALUE _)
{
    rb_f_exec(c, a);
    UNREACHABLE_RETURN(Qnil);
}

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

  • Передача строки command_line в оболочку.

  • Вызов исполняемого файла по пути exe_path.

Этот метод имеет потенциальные уязвимости безопасности, если вызывается с ненадежным вводом; см. Внедрение команд.

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

Аргумент env, если задан, представляет собой хэш, который влияет на ENV для нового процесса; см. Среда выполнения.

Аргумент options представляет собой хэш параметров для нового процесса; см. Параметры выполнения.

Первый обязательный аргумент является одним из следующих:

  • command_line, если это строка, и если она начинается с зарезервированного слова оболочки или специального встроенного средства, или если она содержит один или несколько метасимволов.

  • exe_path в противном случае.

Аргумент command_line

Строковый аргумент command_line представляет собой командную строку, которая должна быть передана в оболочку; она должна начинаться с зарезервированного слова оболочки, начинаться со специального встроенного средства или содержать метасимволы:

exec('if true; then echo "Foo"; fi') # Shell reserved word.
exec('echo')                         # Built-in.
exec('date > date.tmp')              # Contains meta character.

Командная строка также может содержать аргументы и параметры для команды:

exec('echo "Foo"')

Вывод:

Foo

См. Оболочка выполнения для получения подробной информации об оболочке.

Вызывает исключение, если новый процесс не может быть выполнен.

Аргумент exe_path

Аргумент exe_path является одним из следующих:

  • Строковый путь к исполняемому файлу, который нужно вызвать.

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

Пример:

exec('/usr/bin/date')

Вывод:

Sat Aug 26 09:38:00 AM CDT 2023

Ruby вызывает исполняемый файл напрямую, без оболочки и без расширения оболочки:

exec('doesnt_exist') # Raises Errno::ENOENT

Если задан один или несколько args, каждый из них является аргументом или параметром, который должен быть передан исполняемому файлу:

exec('echo', 'C*')
exec('echo', 'hello', 'world')

Вывод:

C*
hello world

Вызывает исключение, если новый процесс не может быть выполнен.

exit(status = true) Show source
exit(status = true)
static VALUE
f_exit(int c, const VALUE *a, VALUE _)
{
    rb_f_exit(c, a);
    UNREACHABLE_RETURN(Qnil);
}

Инициирует завершение скрипта Ruby путем вызова SystemExit; исключение может быть перехвачено. Возвращает код завершения status в базовую операционную систему.

Значения 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 выполняет все процедуры завершения (см. Kernel::at_exit) и все финализаторы объектов (см. ObjectSpace::define_finalizer).

Пример:

at_exit { puts 'In at_exit function.' }
ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' })
exit

Вывод:

In at_exit function.
In finalizer.
exit!(status = false) Show source
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)

Значения true и false для аргумента status указывают на успех и неудачу соответственно; значения целых чисел зависят от системы.

raise
fail
fail(string, cause: $!)
fail(exception [, string [, array]], cause: $!)

Без аргументов, вызывает исключение в $! или возбуждает 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
Псевдоним для: raise
fork { ... } → целое число или nil Показать исходный код
fork → целое число или nil
static VALUE
rb_f_fork(VALUE obj)
{
    rb_pid_t pid;

    pid = rb_call_proc__fork();

    if (pid == 0) {
        if (rb_block_given_p()) {
            int status;
            rb_protect(rb_yield, Qundef, &status);
            ruby_stop(status);
        }
        return Qnil;
    }

    return PIDT2NUM(pid);
}

Создаёт дочерний процесс.

При передаче блока, выполняет его в дочернем процессе; при выходе из блока дочерний процесс завершается со статусом ноль:

puts "Before the fork: #{Process.pid}"
fork do
  puts "In the child process: #{Process.pid}"
end                   # => 382141
puts "After the fork: #{Process.pid}"

Вывод:

Before the fork: 420496
After the fork: 420496
In the child process: 420520

Без блока, функция fork вызывается дважды:

  • Один раз в родительском процессе, возвращая pid дочернего процесса.

  • Один раз в дочернем процессе, возвращая nil.

Пример:

puts "This is the first line before the fork (pid #{Process.pid})"
puts fork
puts "This is the second line after the fork (pid #{Process.pid})"

Вывод:

This is the first line before the fork (pid 420199)
420223
This is the second line after the fork (pid 420199)

This is the second line after the fork (pid 420223)

В любом случае, дочерний процесс может завершиться с помощью Kernel.exit!, чтобы избежать вызова Kernel#at_exit.

Чтобы избежать «зомби-процессов», родительский процесс должен вызвать либо:

  • Process.wait, чтобы получить статусы завершения своих дочерних процессов.

  • Process.detach, чтобы указать отсутствие интереса к их статусам.

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

Обратите внимание, что метод fork доступен на некоторых платформах, но не на всех:

Process.respond_to?(:fork) # => true # Would be false on some.

Если нет, используйте ::spawn вместо fork.

format
Псевдоним для: sprintf
frozen? → true или false Показать исходный код
# File kernel.rb, line 67
def frozen?
  Primitive.attr! :leaf
  Primitive.cexpr! 'rb_obj_frozen_p(self)'
end

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

a = [ "a", "b", "c" ]
a.freeze    #=> ["a", "b", "c"]
a.frozen?   #=> true
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 forward(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_filter_non_literal();
    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, wrap);

    RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));

    return Qtrue;
}

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

Если имя файла — абсолютный путь (например, начинается с ‘/’), файл загружается напрямую по абсолютному пути.

Если имя файла — явный относительный путь (например, начинается с ‘./’ или ‘../’), файл загружается относительно текущего каталога.

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

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

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

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 < ISEQ_BODY(cfp->iseq)->local_table_size; i++) {
                local_var_list_add(&vars, ISEQ_BODY(cfp->iseq)->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 → итератор
# File kernel.rb, line 180
def loop
  unless block_given?
    return enum_for(:loop) { Float::INFINITY }
  end

  begin
    while true
      yield
    end
  rescue StopIteration => e
    e.result
  end
end

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

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

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

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

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

result = loop {
  puts enum.next
} #=> :ok
open(path, mode = 'r', perm = 0666, **opts) → io or nil Показать исходный код
open(path, mode = 'r', perm = 0666, **opts) {|io| ... } → 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)) {
                    // TODO: when removed in 4.0, update command_injection.rdoc
                    rb_warn_deprecated_to_remove_at(4.0, "Calling Kernel#open with a leading '|'", "IO.popen");
                    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, связанный с заданным файлом.

Этот метод может иметь потенциальные уязвимости в безопасности, если вызывается с недоверенными входными данными; см. Ввод команд.

Без блока возвращается поток файла:

open('t.txt') # => #<File:t.txt>

С блоком, блок вызывается с открытым потоком файла, а затем поток закрывается:

open('t.txt') {|f| p f } # => #<File:t.txt (closed)>

Вывод:

#<File:t.txt>

См. File.open для подробностей.

p(object) → obj Показать исходный код
p(*objects) → array of objects
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, выполняется:

$stdout.write(obj.inspect, "\n")

С одним объектом, возвращает объект; с несколькими объектами, возвращает массив содержащий объекты; без объекта, возвращает nil.

Примеры:

r = Range.new(0, 4)
p r                 # => 0..4
p [r, r, r]         # => [0..4, 0..4, 0..4]
p                   # => nil

Вывод:

0..4
[0..4, 0..4, 0..4]

Kernel#p предназначен для отладки. Реализации Ruby могут определить Kernel#p как непрерывный целиком или частично. В CRuby, запись данных Kernel#p не прерывается.

pretty_inspect() Показать исходный код
# File lib/pp.rb, line 637
def pretty_inspect
  PP.pp(self, ''.dup)
end

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

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

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

Эквивалентно $stdout.print(*objects), этот метод является простым способом записи в $stdout.

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

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

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

  • Записывает в stdout.

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

С стандартными разделителями:

objects = [0, 0.0, Rational(0, 1), Complex(0, 0), :zero, 'zero']
$OUTPUT_RECORD_SEPARATOR
$OUTPUT_FIELD_SEPARATOR
print(*objects)

Вывод:

nil
nil
00.00/10+0izerozero

С заданными разделителями:

$OUTPUT_RECORD_SEPARATOR = "\n"
$OUTPUT_FIELD_SEPARATOR = ','
print(*objects)

Вывод:

0,0.0,0/1,0+0i,zero,zero

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

gets  # Sets $_ to the most recent user input.
print # Prints $_.
printf(format_string, *objects) → nil Показать исходный код
printf(io, format_string, *objects) → 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(format_string, *objects))

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

С единственным аргументом format_string, форматирует objects в строку, затем записывает отформатированную строку в $stdout:

printf('%4.4d %10s %2.2f', 24, 24, 24.0)

Вывод (в $stdout):

0024         24 24.00#

С аргументами io и format_string, форматирует objects в строку, затем записывает отформатированную строку в io:

printf($stderr, '%4.4d %10s %2.2f', 24, 24, 24.0)

Вывод (в $stderr):

0024         24 24.00# => nil

Без аргументов, ничего не делает.

proc { |...| block } → a_proc Показать исходный код
static VALUE
f_proc(VALUE _)
{
    return proc_new(rb_cProc, FALSE);
}

Эквивалентно 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 forward(r_stdout, rb_intern("putc"), 1, &ch);
}

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

$stdout.putc(int)

См. IO#putc для важной информации о многобайтовых символах.

puts(*objects) → 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 forward(r_stdout, rb_intern("puts"), argc, argv);
}

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

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

Без аргументов, вызывает исключение в $! или вызывает 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
Также алиас: 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 = $/, chomp: false) → string Показать исходный код
readline(limit, chomp: false) → string
readline(sep, limit, chomp: false) → string
static VALUE
rb_f_readline(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_readline(argc, argv, argf);
    }
    return forward(argf, rb_intern("readline"), argc, argv);
}

Эквивалентно методу Kernel#gets, за исключением того, что он вызывает исключение, если вызывается в конце потока:

$ cat t.txt | ruby -e "p readlines; readline"
["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"]
in `readline': end of file reached (EOFError)

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

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

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

При передаче только строкового аргумента sep возвращает оставшиеся строки, определяемые разделителем строк sep, или nil , если такового нет; см. Разделитель строк:

# Default separator.
$ cat t.txt | ruby -e "p readlines"
["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"]

# Specified separator.
$ cat t.txt | ruby -e "p readlines 'li'"
["First li", "ne\nSecond li", "ne\n\nFourth li", "ne\nFifth li", "ne\n"]

# Get-all separator.
$ cat t.txt | ruby -e "p readlines nil"
["First line\nSecond line\n\nFourth line\nFifth line\n"]

# Get-paragraph separator.
$ cat t.txt | ruby -e "p readlines ''"
["First line\nSecond line\n\n", "Fourth line\nFifth line\n"]

При передаче только целочисленного аргумента limit ограничивает количество байтов в строке; см. Ограничение длины строки:

$cat t.txt | ruby -e "p readlines 10"
["First line", "\n", "Second lin", "e\n", "\n", "Fourth lin", "e\n", "Fifth line", "\n"]

$cat t.txt | ruby -e "p readlines 11"
["First line\n", "Second line", "\n", "\n", "Fourth line", "\n", "Fifth line\n"]

$cat t.txt | ruby -e "p readlines 12"
["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"]

При передаче аргументов sep и limit объединяет оба поведения; см. Разделитель строк и ограничение длины строки.

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

$ cat t.txt | ruby -e "p readlines(chomp: true)"
["First line", "Second line", "", "Fourth line", "Fifth line"]

Необязательные ключевые аргументы enc_opts задают параметры кодирования; см. Параметры кодирования.

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_internal(rb_file_absolute_path(fname, base), false);
}

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

select(read_ios, write_ios = [], error_ios = [], timeout = nil) → array or nil Показать исходный код
static VALUE
rb_f_select(int argc, VALUE *argv, VALUE obj)
{
    VALUE scheduler = rb_fiber_scheduler_current();
    if (scheduler != Qnil) {
        // It's optionally supported.
        VALUE result = rb_fiber_scheduler_io_selectv(scheduler, argc, argv);
        if (!UNDEF_P(result)) return result;
    }

    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), который отслеживает несколько дескрипторов файлов, ожидая, пока один или несколько дескрипторов файлов не станут доступными для какой-либо операции ввода-вывода.

Не реализовано на всех платформах.

Каждый из аргументов read_ios, write_ios, и error_ios представляет собой массив объектов IO.

Аргумент timeout представляет собой целочисленный интервал времени ожидания в секундах.

Метод отслеживает объекты IO, указанные во всех трех массивах, ожидая, пока некоторые из них не станут доступными; возвращает массив из 3 элементов, элементы которого:

  • Массив объектов в read_ios , готовых для чтения.

  • Массив объектов в write_ios , готовых для записи.

  • Массив объектов в error_ios , у которых есть ожидаемые исключения.

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

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, pipe, сокет, когда несколько процессов читают поток.

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

Вызов 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

Пример:

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 принимает до шести параметров:

  • строка с именем события

  • строка с именем файла

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

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

  • связывание или nil

  • класс, модуль или nil

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, class_or_module|
  printf "%8s %s:%-2d %16p %14p\n", event, file, line, id, class_or_module
}
t = Test.new
t.test

Результат:

c-return prog.rb:8   :set_trace_func         Kernel
    line prog.rb:11              nil            nil
  c-call prog.rb:11             :new          Class
  c-call prog.rb:11      :initialize    BasicObject
c-return prog.rb:11      :initialize    BasicObject
c-return prog.rb:11             :new          Class
    line prog.rb:12              nil            nil
    call prog.rb:2             :test           Test
    line prog.rb:3             :test           Test
    line prog.rb:4             :test           Test
  return prog.rb:5             :test           Test
sleep(secs = nil) → slept_secs Показать исходный код
static VALUE
rb_f_sleep(int argc, VALUE *argv, VALUE _)
{
    time_t beg = time(0);
    VALUE scheduler = rb_fiber_scheduler_current();

    if (scheduler != Qnil) {
        rb_fiber_scheduler_kernel_sleepv(scheduler, argc, argv);
    }
    else {
        if (argc == 0 || (argc == 1 && NIL_P(argv[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);
}

Приостанавливает выполнение текущей потока на заданное количество секунд, указанное числовым аргументом secs, или навсегда, если secs равно nil; возвращает целое число, равное количеству приостановленных секунд (округленное).

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_line, options = {}) → pid Показать исходный код
spawn([env, ] exe_path, *args, 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
}

Создает новый дочерний процесс, выполнив одно из следующих действий в этом процессе:

  • Передаёт строку command_line оболочке.

  • Вызывает исполняемый файл по адресу exe_path.

Этот метод имеет потенциальные уязвимости в области безопасности, если используется с ненадежными входными данными; см. Внедрение кода в команды.

Возвращает идентификатор процесса (pid) нового процесса без ожидания его завершения.

Для предотвращения появления процессов-зомби родительский процесс должен вызвать:

  • Process.wait, чтобы собрать статусы завершения своих дочерних процессов.

  • Process.detach, чтобы прекратить заинтересованность в их статусе.

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

Аргумент env, если он указан, является хэш-таблицей, которая влияет на ENV для нового процесса; см. Окружающая среда выполнения.

Аргумент options — это хэш-таблица опций для нового процесса; см. Опции выполнения.

Первый обязательный аргумент — один из следующих:

  • command_line , если это строка, и если она начинается со слова, зарезервированного оболочкой, или со специального встроенного элемента, или если она содержит один или несколько метасимволов.

  • exe_path в противном случае.

Аргумент command_line

Строковый аргумент command_line — это командная строка, которая передается оболочке; она должна начинаться со слова, зарезервированного оболочкой, или со специального встроенного элемента, или содержать метасимволы:

spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word.
Process.wait                          # => 798847
spawn('echo')                         # => 798848 # Built-in.
Process.wait                          # => 798848
spawn('date > /tmp/date.tmp')         # => 798879 # Contains meta character.
Process.wait                          # => 798849
spawn('date > /nop/date.tmp')         # => 798882 # Issues error message.
Process.wait                          # => 798882

Командная строка также может содержать аргументы и опции для команды:

spawn('echo "Foo"') # => 799031
Process.wait        # => 799031

Вывод:

Foo

Подробности об оболочке см. в разделе Оболочка выполнения.

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

Аргумент exe_path

Аргумент exe_path — это одно из следующих:

  • Путь к исполняемому файлу, который необходимо вызвать:

    spawn('/usr/bin/date') # Path to date on Unix-style system.
    Process.wait
    

    Вывод:

    Thu Aug 31 10:06:48 AM CDT 2023
  • Массив из двух элементов, содержащий путь к исполняемому файлу и строку, используемую в качестве имени исполняемого процесса:

    pid = spawn(['sleep', 'Hello!'], '1') # 2-element array.
    p `ps -p #{pid} -o command=`
    

    Вывод:

    "Hello! 1\n"
    

Ruby вызывает исполняемый файл напрямую без оболочки и без расширения оболочки.

Если указан один или несколько args, каждый из них является аргументом или опцией, передаваемыми исполняемому файлу:

spawn('echo', 'C*')             # => 799392
Process.wait                    # => 799392
spawn('echo', 'hello', 'world') # => 799393
Process.wait                    # => 799393

Вывод:

C*
hello world

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

sprintf(format_string *objects) → string Показать исходный код
static VALUE
f_sprintf(int c, const VALUE *v, VALUE _)
{
    return rb_f_sprintf(c, v);
}

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

Подробности о format_string, см. в Спецификациях форматирования.

Также алиас: 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(integer_callno, *arguments) → 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
}

Вызывает системный вызов Posix syscall(2), который вызывает указанную функцию.

Вызывает функцию операционной системы, идентифицируемую integer_callno; возвращает результат функции или вызывает SystemCallError, если функция завершилась неудачно. Эффект вызова зависит от платформы. Аргументы и возвращаемое значение зависят от платформы.

Для каждого из arguments: если это целое число, оно передается напрямую; если это строка, она интерпретируется как двоичная последовательность байтов. Может быть до девяти таких аргументов.

Аргументы integer_callno и argument, а также возвращаемое значение зависят от платформы.

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

Не реализовано на всех платформах.

system([env, ] command_line, options = {}, exception: false) → true, false, or nil Показать исходный код
system([env, ] exe_path, *args, options = {}, exception: false) → true, false, or nil
static VALUE
rb_f_system(int argc, VALUE *argv, VALUE _)
{
    rb_thread_t *th = GET_THREAD();
    VALUE execarg_obj = rb_execarg_new(argc, argv, TRUE, TRUE);
    struct rb_execarg *eargp = rb_execarg_get(execarg_obj);

    struct rb_process_status status = {0};
    eargp->status = &status;

    last_status_clear(th);

    // This function can set the thread's last status.
    // May be different from waitpid_state.pid on exec failure.
    rb_pid_t pid = rb_execarg_spawn(execarg_obj, 0, 0);

    if (pid > 0) {
        VALUE status = rb_process_status_wait(pid, 0);
        struct rb_process_status *data = rb_check_typeddata(status, &rb_process_status_type);
        // Set the last status:
        rb_obj_freeze(status);
        th->last_status = status;

        if (data->status == EXIT_SUCCESS) {
            return Qtrue;
        }

        if (data->error != 0) {
            if (eargp->exception) {
                VALUE command = eargp->invoke.sh.shell_script;
                RB_GC_GUARD(execarg_obj);
                rb_syserr_fail_str(data->error, command);
            }
            else {
                return Qnil;
            }
        }
        else 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, data->status), ": ");
            rb_str_append(str, command);
            RB_GC_GUARD(execarg_obj);
            rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
        }
        else {
            return Qfalse;
        }

        RB_GC_GUARD(status);
    }

    if (eargp->exception) {
        VALUE command = eargp->invoke.sh.shell_script;
        RB_GC_GUARD(execarg_obj);
        rb_syserr_fail_str(errno, command);
    }
    else {
        return Qnil;
    }
}

Создает новый дочерний процесс, выполнив одно из следующих действий в этом процессе:

  • Передаёт строку command_line оболочке.

  • Вызывает исполняемый файл по адресу exe_path.

Этот метод имеет потенциальные уязвимости в области безопасности, если используется с ненадежными входными данными; см. Внедрение кода в команды.

Возвращает:

  • true , если команда завершается со статусом ноль.

  • false , если код выхода — ненулевое целое число.

  • nil , если команда не может быть выполнена.

Вызывает исключение (вместо возврата false или nil) если ключевой аргумент exception установлен в true.

Присваивает код ошибки команды переменной $?.

Новый процесс создается с помощью системного вызова system; он может унаследовать некоторые из своих переменных среды от вызывающей программы (возможно, включая открытые дескрипторы файлов).

Аргумент env, если он указан, является хэш-таблицей, которая влияет на ENV для нового процесса; см. Окружающая среда выполнения.

Аргумент options — это хэш-таблица опций для нового процесса; см. Опции выполнения.

Первый обязательный аргумент — один из следующих:

  • command_line , если это строка, и если она начинается со слова, зарезервированного оболочкой, или со специального встроенного элемента, или если она содержит один или несколько метасимволов.

  • exe_path в противном случае.

Аргумент command_line

Строковый аргумент command_line — это командная строка, которая передается оболочке; она должна начинаться со слова, зарезервированного оболочкой, или со специального встроенного элемента, или содержать метасимволы:

system('if true; then echo "Foo"; fi')          # => true  # Shell reserved word.
system('echo')                                  # => true  # Built-in.
system('date > /tmp/date.tmp')                  # => true  # Contains meta character.
system('date > /nop/date.tmp')                  # => false
system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.

Присваивает код ошибки команды переменной $?:

system('echo')                             # => true  # Built-in.
$?                                         # => #<Process::Status: pid 640610 exit 0>
system('date > /nop/date.tmp')             # => false
$?                                         # => #<Process::Status: pid 640742 exit 2>

Командная строка также может содержать аргументы и опции для команды:

system('echo "Foo"') # => true

Вывод:

Foo

Подробности об оболочке см. в разделе Оболочка выполнения.

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

Аргумент exe_path

Аргумент exe_path — это одно из следующих:

  • Путь к исполняемому файлу, который необходимо вызвать.

  • Массив из двух элементов, содержащий путь к исполняемому файлу и строку, используемую в качестве имени исполняемого процесса.

Пример:

system('/usr/bin/date') # => true # Path to date on Unix-style system.
system('foo')           # => nil  # Command failed.

Вывод:

Mon Aug 28 11:43:10 AM CDT 2023

Присваивает код ошибки команды переменной $?:

system('/usr/bin/date') # => true
$?                      # => #<Process::Status: pid 645605 exit 0>
system('foo')           # => nil
$?                      # => #<Process::Status: pid 645608 exit 127>

Ruby вызывает исполняемый файл напрямую без оболочки и без расширения оболочки:

system('doesnt_exist') # => nil

Если указан один или несколько args, каждый из них является аргументом или опцией, передаваемыми исполняемому файлу:

system('echo', 'C*')             # => true
system('echo', 'hello', 'world') # => true

Вывод:

C*
hello world

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

tap {|x| блок } → 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 setgid bit set
"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| блок } → an_object Показать исходный код
# File kernel.rb, line 129
def then
  unless block_given?
    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| URI(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

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

require 'open-uri'
require 'json'

construct_url(arguments).
  then {|url| URI(url).read }.
  then {|response| JSON.parse(response) }
throw(метка [, 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, ожидающего метки метка. Вызывает UncaughtThrowError , если для метки метка нет блока catch. Необязательный второй параметр предоставляет возвращаемое значение для блока catch, которое в противном случае по умолчанию равно nil. Примеры см. в Kernel::catch.

trace_var(символ, cmd ) → nil Показать исходный код
trace_var(символ) {|val| блок } → 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(сигнал, команда ) → obj Показать исходный код
trap(сигнал) {| | блок } → 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(символ [, cmd] ) → массив или 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")

Результат:

warning 1
warning 2

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

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

def bar
  foo
end

bar

Результат:

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

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

:deprecated

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

:experimental

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

yield_self {|x| блок } → an_object Показать исходный код
# File kernel.rb, line 144
def yield_self
  unless block_given?
    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"

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

JSON(object, *args) Показать исходный код
# File ext/json/lib/json/common.rb, line 679
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.

URI(uri) Показать исходный код
# File lib/uri/common.rb, line 842
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, который может быть строкой URI или существующим объектом URI:

# Returns a new URI.
uri = URI('http://github.com/ruby/ruby')
# => #<URI::HTTP http://github.com/ruby/ruby>
# Returns the given URI.
URI(uri)
# => #<URI::HTTP http://github.com/ruby/ruby>
gem(gem_name, *requirements) Показать исходный код
# File lib/rubygems/core_ext/kernel_gem.rb, line 35
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.is_a? 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 657
def j(*objs)
  objs.each do |obj|
    puts JSON::generate(obj, :allow_nan => true, :max_nesting => false)
  end
  nil
end

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

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

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

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

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

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

Также алиас: pp
require(path) Показать исходный код
# File lib/rubygems/core_ext/kernel_require.rb, line 36
def require(path) # :doc:
  return gem_original_require(path) unless Gem.discover_gems_on_require

  RUBYGEMS_ACTIVATION_MONITOR.synchronize do
    path = File.path(path)

    if spec = Gem.find_unresolved_default_spec(path)
      # Ensure -I beats a default gem
      resolved_path = begin
        rp = nil
        load_path_check_index = Gem.load_path_insert_index - Gem.activated_gem_paths
        Gem.suffixes.find do |s|
          $LOAD_PATH[0...load_path_check_index].find do |lp|
            if File.symlink? lp # for backward compatibility
              next
            end

            full_path = File.expand_path(File.join(lp, "#{path}#{s}"))
            rp = full_path if File.file?(full_path)
          end
        end
        rp
      end

      Kernel.send(:gem, spec.name, Gem::Requirement.default_prerelease) unless
        resolved_path
    end

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

    if Gem::Specification.unresolved_deps.empty?
      next
    end

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

    if Gem::Specification.find_active_stub_by_path(path)
      next
    end

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

    found_specs = Gem::Specification.find_in_unresolved path

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

      found_specs.each(&:activate)

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

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

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

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

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

      valid.activate
    end
  end

  begin
    gem_original_require(path)
  rescue LoadError => load_error
    if load_error.path == path &&
       RUBYGEMS_ACTIVATION_MONITOR.synchronize { Gem.try_activate(path) }

      return gem_original_require(path)
    end

    raise load_error
  end
end

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

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

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

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

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

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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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