Spec-Zone.ru › Ruby 3.4

модуль 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`: Возвращает стандартный вывод выполнения 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 865
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 692
def pp(*objs)
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

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

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

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

__callee__ → символ
Исходный код
static VALUE
rb_f_callee_name(VALUE _)
{
    ID fname = prev_frame_callee(); /* need *callee* ID */

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

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

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

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

__method__ → символ
Исходный код
static VALUE
rb_f_method_name(VALUE _)
{
    ID fname = prev_frame_func(); /* need *method* ID */

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

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

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

    StringValue(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{...} использует этот метод.

Array(object) → object или новый_массив
Исходный код
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]
Complex(real, imag = 0, exception: true) → комплексное число или nil
Complex(s, exception: true) → комплексное число или nil
Исходный код
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

    if (rb_scan_args(argc, argv, "11:", &a1, &a2, &opts) == 1) {
        a2 = Qundef;
    }
    if (!NIL_P(opts)) {
        raise = rb_opts_exception_p(opts, raise);
    }
    if (argc > 0 && CLASS_OF(a1) == rb_cComplex && 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) → число с плавающей точкой или nil
Исходный код
# File kernel.rb, line 193
def Float(arg, exception: true)
  if Primitive.mandatory_only?
    Primitive.rb_f_float1(arg)
  else
    Primitive.rb_f_float(arg, exception)
  end
end

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

Float(1)                 #=> 1.0
Float("123.456")         #=> 123.456
Float("123.0_badstring") #=> ArgumentError: invalid value for Float(): "123.0_badstring"
Float(nil)               #=> TypeError: can't convert nil into Float
Float("123.0_badstring", exception: false)  #=> nil
Hash(object) → object или новый_хеш
Исходный код
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) → целое число или nil
Исходный код
# File kernel.rb, line 286
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) → путь
Исходный код
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
    if (CLASS_OF(str) == rb_cPathname)
        return str;
    return rb_class_new_instance(1, &str, rb_cPathname);
}

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

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

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

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

Rational(x, y, exception: true) → рациональное число или nil
Rational(arg, exception: true) → рациональное число или nil
Исходный код
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

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

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

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

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

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

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

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

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

См. также String#to_r.

String(object) → объект или новая_строка
Исходный код
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 не может быть преобразовано в строку.

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 { блок } → процедура
Исходный код
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;
}

Преобразует блок в объект 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);
}

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

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

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

autoload?(name, inherit=true) → Строка или 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"

module C
  autoload(:D, "d")
  autoload?(:D)          #=> "d"
  autoload?(:B)          #=> nil
end

class E
  autoload(:F, "f")
  autoload?(:F)          #=> "f"
  autoload?(:B)          #=> "b"
end
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 или 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"
END_OF_DOCUMENT_MARKER
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) → массив или nil
caller(range) → массив или 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) → массив или nil
caller_locations(range) → массив или nil
Исходный код
static VALUE
rb_f_caller_locations(int argc, VALUE *argv, VALUE _)
{
    return ec_backtrace_to_ary(GET_EC(), argc, argv, 1, 1, 0);
}

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

Дополнительную информацию см. в Thread::Backtrace::Location.

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

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

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

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

catch([tag]) {|tag| block } → obj
Исходный код
static VALUE
rb_f_catch(int argc, VALUE *argv, VALUE self)
{
    VALUE tag = rb_check_arity(argc, 0, 1) ? argv[0] : rb_obj_alloc(rb_cObject);
    return rb_catch_obj(tag, catch_i, 0);
}

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

catch(1) { 123 }            # => 123

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

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

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

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

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

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

  puts "This puts is displayed"
  456
end

# => 456

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

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

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

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

chop → $_
Исходный код
static VALUE
rb_f_chop(VALUE _)
{
    VALUE str = rb_funcall_passing_block(uscore_get(), rb_intern("chop"), 0, 0);
    rb_lastline_set(str);
    return str;
}

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

class → класс
Исходный код
# 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) → объект
Исходный код
# File kernel.rb, line 47
def clone(freeze: nil)
  Primitive.rb_obj_clone2(freeze)
end

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

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

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

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

    rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
    StringValue(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 = {})
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('exit')                         # 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 вызывает исполняемый файл напрямую. Этот вариант не использует оболочку; см. Аргументы args для ограничений.

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

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

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

Вывод:

C*
hello world

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

exit(status = true)
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)
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 соответствуют, соответственно, успеху и ошибке; значения целочисленных кодов зависят от операционной системы.

fail
Псевдоним для: raise
fork { ... } → целое число или null
fork → целое число или null
Исходный код
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);
}

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

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

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 возвращается дважды:

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

  • В дочернем процессе, возвращая 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

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

a = [ "a", "b", "c" ]
a.freeze    #=> ["a", "b", "c"]
a.frozen?   #=> true
gets(sep=$/ [, getline_args]) → строка или null
gets(limit [, getline_args]) → строка или null
gets(sep, limit [, getline_args]) → строка или null
Исходный код
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) {|...| блок } → $_
Исходный код
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 { |...| блок } → 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 { блок }
loop → перечислитель
Исходный код
# File kernel.rb, line 160
def loop
  Primitive.attr! :inline_block
  unless defined?(yield)
    return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, rb_f_loop_size)'
  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) → поток или 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) → массив объектов
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 685
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 $_.
END_OF_DOCUMENT_MARKER
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(exception, message = exception.to_s, backtrace = nil, cause: $!)
raise(message = nil, cause: $!)
Исходный код
static VALUE
f_raise(int c, VALUE *v, VALUE _)
{
    return rb_f_raise(c, v);
}

Вызывает исключение; см. Исключения.

Аргумент exception задаёт класс нового исключения; он должен быть классом Exception или одним из его подклассов (чаще всего, RuntimeError или StandardError), или экземпляром одного из этих классов:

begin
  raise(StandardError)
rescue => x
  p x.class
end
# => StandardError

Аргумент message задаёт сохранённое сообщение в новом исключении, которое можно получить методом Exception#message; сообщение должно быть объектом, преобразуемым в строку string-convertible object или nil:

begin
  raise(StandardError, 'Boom')
rescue => x
  p x.message
end
# => "Boom"

Если аргумент message не указан, сообщением является имя класса исключения.

См. Сообщения.

Аргумент backtrace может быть использован для изменения трассировки стека нового исключения, как сообщается Exception#backtrace и Exception#backtrace_locations; трассировка стека должна быть массивом Thread::Backtrace::Location, массивом строк, одиночной строкой или nil.

Использование массива Thread::Backtrace::Location экземпляров является наиболее согласованным вариантом и должно предпочтительно использоваться, когда это возможно. Необходимое значение можно получить из caller_locations или скопировать из Exception#backtrace_locations другой ошибки:

begin
  do_some_work()
rescue ZeroDivisionError => ex
  raise(LogicalError, "You have an error in your math", ex.backtrace_locations)
end

Способы, как Exception#backtrace и Exception#backtrace_locations поднятого исключения, устанавливаются в одну и ту же трассировку стека.

Когда желаемый стек расположений недоступен и должен быть построен заново, можно использовать массив строк или одиночную строку. В этом случае устанавливается только Exception#backtrace:

begin
  raise(StandardError, 'Boom', %w[dsl.rb:3 framework.rb:1])
rescue => ex
  p ex.backtrace
  # => ["dsl.rb:3", "framework.rb:1"]
  p ex.backtrace_locations
  # => nil
end

Если аргумент backtrace не указан, трассировка стека устанавливается в соответствии с массивом Thread::Backtrace::Location объектов, полученных из стека вызовов.

См. Трассировки стека.

Ключевой аргумент cause устанавливает сохранённую причину в новом исключении, которую можно получить методом Exception#cause; причина должна быть объектом исключения (Exception или одним из его подклассов) или nil:

begin
  raise(StandardError, cause: RuntimeError.new)
rescue => x
  p x.cause
end
# => #<RuntimeError: RuntimeError>

Если ключевой аргумент cause не указан, причина - это значение $!.

См. Причина.

В альтернативном порядке вызова, где аргумент exception не указан, поднимается новое исключение класса, заданного $!, или класса RuntimeError, если $! является nil:

begin
  raise
rescue => x
  p x
end
# => RuntimeError

Если аргумент exception не указан, аргумент message и ключевой аргумент cause могут быть указаны, но аргумент backtrace не может быть указан.

Также алиас: 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) → массив
readlines(limit, chomp: false, **enc_opts) → массив
readlines(sep, limit, chomp: false, **enc_opts) → массив
Исходный код
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 или 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) → массив или 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 представляет собой числовое значение (например, целое или вещественное число) интервал времени ожидания в секундах.

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

  • Массив объектов в read_ios, которые готовы к чтению.

  • Массив объектов в write_ios, которые готовы к записи.

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

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

IO.select просматривает буфер объектов ввода-вывода для проверки возможности чтения. Если буфер ввода-вывода не пуст, IO.select немедленно сообщает о возможности чтения. Эта «проверка» происходит только для объектов ввода-вывода. Она не происходит для объектов, подобных объектам ввода-вывода, таким как 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 предпочтительно для объектов ввода-вывода, таких как 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('exit')                         # => 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 — один из следующих:

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

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

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

    Вывод:

    Mon Aug 28 11:43:10 AM CDT 2023

Ruby вызывает исполняемый файл напрямую. Этот вариант не использует оболочку; см. Аргументы args для замечаний.

Если задан один или несколько 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. Возвращает предыдущее значение seed.

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

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

srand 1234               # => 268519324636777531569100071560086917274
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
[ rand(10), rand(1000) ] # => [4, 664]
srand 1234               # => 1234
[ rand, rand ]           # => [0.1915194503788923, 0.6221087710398319]
sub(pattern, replacement) → $_
sub(pattern) {|...| block } → $_
Исходный код
static VALUE
rb_f_sub(int argc, VALUE *argv, VALUE _)
{
    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)) {
            StringValue(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, или nil
system([env, ] exe_path, *args, options = {}, exception: false) → true, false, или 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('exit')                                  # => 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('exit')                             # => 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 — это одно из следующего:

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

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

Пример:

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 вызывает исполняемый файл напрямую. Этот вариант не использует оболочку; см. Аргументы args для предостережений.

system('doesnt_exist') # => nil

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

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

Вывод:

C*
hello world

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

tap {|x| block } → obj
Исходный код
# File kernel.rb, line 89
def tap
  Primitive.attr! :inline_block
  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(char, path0, path1 = nil) → object
Исходный код
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);
}

Выполняет тест для одного или обоих объектов файловой системы по указанным путям path0 и path1:

  • Каждый путь path0 или path1 указывает на файл, каталог, устройство, канал и т. д.

  • Символ char выбирает конкретный тест.

Тесты:

  • Каждый из этих тестов работает только с объектом по пути path0, и возвращает true или false; для несуществующего объекта возвращает false (не вызывает исключение):

    Символ Тест
    'b' Является ли объект блочным устройством.
    'c' Является ли объект символьным устройством.
    'd' Является ли объект каталогом.
    'e' Существует ли объект.
    'f' Является ли объект существующим обычным файлом.
    'g' Установлен ли бит setgid для объекта.
    'G' Соответствует ли группа владельца объекта группе вызывающего.
    'k' Установлен ли бит sticky для объекта.
    'l' Является ли объект символической ссылкой.
    'o' Принадлежит ли объект эффективному идентификатору пользователя вызывающего.
    'O' Как 'o', но использует реальный идентификатор пользователя (а не эффективный).
    'p' Является ли объект FIFO-устройством (именованным каналом).
    'r' Доступен ли объект для чтения эффективным идентификатором пользователя/группы вызывающего.
    'R' Как 'r', но использует реальный идентификатор пользователя/группы (а не эффективный).
    'S' Является ли объект сокетом.
    'u' Установлен ли бит setuid для объекта.
    'w' Доступен ли объект для записи эффективным идентификатором пользователя/группы вызывающего.
    'W' Как 'w', но использует реальный идентификатор пользователя/группы (а не эффективный).
    'x' Доступен ли объект для выполнения эффективным идентификатором пользователя/группы вызывающего.
    'X' Как 'x', но использует реальный идентификатор пользователя/группы (а не эффективный).
    'z' Существует ли объект нулевой длины.
  • Этот тест работает только с объектом по пути path0, и возвращает целочисленный размер или nil:

    Символ Тест
    's' Возвращает положительный целочисленный размер, если объект существует и имеет ненулевую длину, nil в противном случае.
  • Каждый из этих тестов работает только с объектом по пути path0, и возвращает объект Time; вызывает исключение, если объекта не существует:

    Символ Тест
    'A' Время последнего доступа к объекту.
    'C' Время последнего изменения объекта.
    'M' Время последней модификации объекта.
  • Каждый из этих тестов работает со временем последней модификации (mtime) каждого из объектов по путям path0 и path1, и возвращает true или false; возвращает false если какой-либо из объектов не существует:

    Символ Тест
    '<' Является ли 'mtime` в `path0` меньше, чем в `path1`.
    '=' Равны ли 'mtime` в `path0` и `path1`.
    '>' Является ли 'mtime` в `path0` больше, чем в `path1`.
  • Этот тест работает с содержимым каждого из объектов по путям path0 и path1, и возвращает true или false; возвращает false если какой-либо из объектов не существует:

    Символ Тест
    '-' Существуют ли объекты и идентичны ли они.
then {|x| block } → an_object
Исходный код
# File kernel.rb, line 121
def then
  Primitive.attr! :inline_block
  unless defined?(yield)
    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
Также алиасирован как: yield_self
throw(tag [, obj])
Исходный код
static VALUE
rb_f_throw(int argc, VALUE *argv, VALUE _)
{
    VALUE tag, value;

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

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

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

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

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

результат:

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

    rb_check_arity(argc, 1, 2);

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

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

    if (rb_obj_is_proc(cmd) &&
        !rb_ractor_main_p() && !rb_ractor_shareable_p(cmd)) {
        cmd = rb_proc_isolate(cmd);
    }

    return trap(sig, func, cmd);
}

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

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

результат:

Terminating: 27461
Child died
Terminating: 27460
END_OF_DOCUMENT_MARKER
untrace_var(symbol [, 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 52
def warn(*msgs, uplevel: nil, category: nil)
  if Primitive.cexpr!("NIL_P(category)")
    Primitive.rb_warn_m(msgs, uplevel, nil)
  elsif Warning[category = Primitive.cexpr!("rb_to_symbol_type(category)")]
    Primitive.rb_warn_m(msgs, uplevel, category)
  end
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

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

:performance

Используется для предупреждения об API или шаблонах, имеющих негативное влияние на производительность.

yield_self
Псевдоним для: then

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

JSON (object, *args)
Исходный код
# File ext/json/lib/json/common.rb, line 873
def JSON(object, *args)
  if object.is_a?(String)
    return JSON.parse(object, args.first)
  elsif object.respond_to?(:to_str)
    str = object.to_str
    if str.is_a?(String)
      return JSON.parse(object.to_str, args.first)
    end
  end

  JSON.generate(object, args.first)
end

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

Аргумент opts передаётся в функцию генерации/разбора соответственно. См. документацию по функциям generate и parse.

URI (uri)
Исходный код
# File lib/uri/common.rb, line 865
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 — это список требований к версии, которым должен соответствовать указанный gem, чаще всего «= example.version.number». См. Gem::Requirement для того, как указать требование к версии.

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

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

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

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

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

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

Пример:

GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
j (*objs)
Исходный код
# File ext/json/lib/json/common.rb, line 851
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 860
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 692
def pp(*objs)
  objs.each {|obj|
    PP.pp(obj)
  }
  objs.size <= 1 ? objs.first : objs
end

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

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 +path+ belongs to a default gem, we activate it and then go straight
    # to normal require

    if spec = Gem.find_default_spec(path)
      name = spec.name

      next if Gem.loaded_specs[name]

      # 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, name, Gem::Requirement.default_prerelease) unless
        resolved_path

      next
    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 заменяется собственным методом, способным загружать gems по требованию.

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

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

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

Сохраняется обычная функциональность 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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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