Spec-Zone.ru › Ruby 3.4

модуль Kernel

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

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

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

Что здесь есть

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

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

  • Получения информации

  • Завершения работы

  • Исключений

  • Ввода-вывода

  • Процедур Proc

  • Трассировки

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

  • Загрузки

  • Передачи управления блоку

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

  • Прочего

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

  • 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, ожидающего заданную метку.

Ввод-вывод

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

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

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

  • p: Выводит результат inspect для заданных объектов в стандартный вывод.

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

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

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

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

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

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

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

Процедуры Proc

  • lambda: Возвращает процедуру 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 869
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__ → symbol Показать исходный код
static VALUE
rb_f_callee_name(VALUE _)
{
    ID fname = prev_frame_callee(); /* need *callee* ID */

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

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

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

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

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

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

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

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

    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 or new_array Показать исходный код
static VALUE
rb_f_array(VALUE obj, VALUE arg)
{
    return rb_Array(arg);
}

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

Сначала пытается преобразовать object в массив с помощью to_ary, а затем — с помощью to_a:

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

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

Array(:foo)             # => [:foo]
Complex(real, imag = 0, exception: true) → complex or nil Показать исходный код
Complex(s, exception: true) → complex or nil
static VALUE
nucomp_f_complex(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

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

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

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

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

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

    • Числовые подстроки действительной и мнимой частей, разделённые знаком (с завершающим символом 'i'):

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

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

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

    Complex('1/2@3/4')   # => (0.36584443443691045+0.34081938001166706i)
    Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i)
    Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i)
    Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i)
    Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i)
    
Float(arg, exception: true) → float or 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 or new_hash Показать исходный код
static VALUE
rb_f_hash(VALUE obj, VALUE arg)
{
    return rb_Hash(arg);
}

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

  • Если object — это:

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

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

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

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

Примеры:

Hash({foo: 0, bar: 1}) # => {:foo=>0, :bar=>1}
Hash(nil)              # => {}
Hash([])               # => {}
Integer(object, base = 0, exception: true) → integer or 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) → pathname Показать исходный код
static VALUE
path_f_pathname(VALUE self, VALUE str)
{
    if (CLASS_OF(str) == rb_cPathname)
        return str;
    return rb_class_new_instance(1, &str, rb_cPathname);
}

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

Чтобы использовать этот конструктор, сначала необходимо подключить стандартное расширение Pathname.

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

Дополнительную информацию см. также в Pathname::new.

Rational(x, y, exception: true) → rational or nil Показать исходный код
Rational(arg, exception: true) → rational or nil
static VALUE
nurat_f_rational(int argc, VALUE *argv, VALUE klass)
{
    VALUE a1, a2, opts = Qnil;
    int raise = TRUE;

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

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

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

Сначала пытается преобразовать object в строку с помощью to_str, а затем — с помощью to_s:

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

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

abort Показать исходный код
abort(msg = nil)
static VALUE
f_abort(int c, const VALUE *a, VALUE _)
{
    rb_f_abort(c, a);
    UNREACHABLE_RETURN(Qnil);
}

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

Если задан строковый аргумент msg, он выводится в STDERR перед завершением; в противном случае, если было вызвано исключение, выводятся его сообщение и трассировка стека.

at_exit { block } → proc Показать исходный код
static VALUE
rb_f_at_exit(VALUE _)
{
    VALUE proc;

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

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

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

выводит:

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

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

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

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

autoload?(name, inherit=true) → String or nil Показать исходный код
static VALUE
rb_f_autoload_p(int argc, VALUE *argv, VALUE obj)
{
    /* use rb_vm_cbase() as same as rb_f_autoload. */
    VALUE klass = rb_vm_cbase();
    if (NIL_P(klass)) {
        return Qnil;
    }
    return rb_mod_autoload_p(argc, argv, klass);
}

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

autoload(:B, "b")
autoload?(:B)            #=> "b"

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 → a_binding Показать исходный код
static VALUE
rb_f_binding(VALUE self)
{
    return rb_binding_new();
}

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

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

  def get_binding
    binding
  end
end

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

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

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

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

  # ...Some implementation ...
end

validate(:name, :empty?, if: false) # skips validation
validate(:name, :empty?, if: true) # performs validation
block_given? → true or false Показать исходный код
static VALUE
rb_f_block_given_p(VALUE _)
{
    rb_execution_context_t *ec = GET_EC();
    rb_control_frame_t *cfp = ec->cfp;
    cfp = vm_get_ruby_level_caller_cfp(ec, RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp));

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

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

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

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

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

caller(start=1, length=nil) → array or nil Показать исходный код
caller(range) → array or nil
static VALUE
rb_f_caller(int argc, VALUE *argv, VALUE _)
{
    return ec_backtrace_to_ary(GET_EC(), argc, argv, 1, 1, 1);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

catch(1) { 123 }            # => 123

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

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

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

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

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

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

  puts "This puts is displayed"
  456
end

# => 456

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

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

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

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

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

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

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

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

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

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

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

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

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

    rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
    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 выполняет все процедуры at-exit (см. 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 { ... } → integer or nil Показать исходный код
fork → integer or nil
static VALUE
rb_f_fork(VALUE obj)
{
    rb_pid_t pid;

    pid = rb_call_proc__fork();

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

    return PIDT2NUM(pid);
}

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

Если передан блок, выполняет его в дочернем процессе; после завершения блока дочерний процесс завершается со статусом 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 возвращает управление дважды:

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

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

Пример:

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

Вывод:

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

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

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

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

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

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

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

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

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

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

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

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

a = [ "a", "b", "c" ]
a.freeze    #=> ["a", "b", "c"]
a.frozen?   #=> true
gets(sep=$/ [, getline_args]) → string or nil Показать исходный код
gets(limit [, getline_args]) → string or nil
gets(sep, limit [, getline_args]) → string or nil
static VALUE
rb_f_gets(int argc, VALUE *argv, VALUE recv)
{
    if (recv == argf) {
        return argf_gets(argc, argv, argf);
    }
    return forward(argf, idGets, argc, argv);
}

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

ARGV << "testfile"
print while gets

выводит:

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

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

global_variables → array Показать исходный код
static VALUE
f_global_variables(VALUE _)
{
    return rb_f_global_variables();
}

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

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

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

iterator? → true or false Показать исходный код
static VALUE
rb_f_iterator_p(VALUE self)
{
    rb_warn_deprecated("iterator?", "block_given?");
    return rb_f_block_given_p(self);
}

Устарел. Вместо него используйте block_given?.

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

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

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

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

    orig_fname = rb_get_path_check_to_string(fname);
    fname = rb_str_encode_ospath(orig_fname);
    RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));

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

    RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));

    return Qtrue;
}

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

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

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

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

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

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

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

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

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

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

fred = 1
for i in 1..10
   # ...
end
local_variables   #=> [:fred, :i]
loop { block } Показать исходный код
loop → an_enumerator
# 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 возвращает значение «result», сохраненное в исключении.

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

result = loop {
  puts enum.next
} #=> :ok
open(path, mode = 'r', perm = 0666, **opts) → io or nil Показать исходный код
open(path, mode = 'r', perm = 0666, **opts) {|io| ... } → obj
static VALUE
rb_f_open(int argc, VALUE *argv, VALUE _)
{
    ID to_open = 0;
    int redirect = FALSE;

    if (argc >= 1) {
        CONST_ID(to_open, "to_open");
        if (rb_respond_to(argv[0], to_open)) {
            redirect = TRUE;
        }
        else {
            VALUE tmp = argv[0];
            FilePathValue(tmp);
            if (NIL_P(tmp)) {
                redirect = TRUE;
            }
            else {
                VALUE cmd = check_pipe_command(tmp);
                if (!NIL_P(cmd)) {
                    // TODO: when removed in 4.0, update command_injection.rdoc
                    rb_warn_deprecated_to_remove_at(4.0, "Calling Kernel#open with a leading '|'", "IO.popen");
                    argv[0] = cmd;
                    return rb_io_s_popen(argc, argv, rb_cIO);
                }
            }
        }
    }
    if (redirect) {
        VALUE io = rb_funcallv_kw(argv[0], to_open, argc-1, argv+1, RB_PASS_CALLED_KEYWORDS);

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

Создает объект IO, связанный с указанным файлом.

При вызове с недоверенными данными этот метод может создать уязвимости безопасности; см. инъекция команд.

Если блок не передан, возвращается файловый поток:

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

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

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

Вывод:

#<File:t.txt>

Подробности см. в File.open.

p(object) → obj Показать исходный код
p(*objects) → array of objects
p → nil
static VALUE
rb_f_p(int argc, VALUE *argv, VALUE self)
{
    int i;
    for (i=0; i<argc; i++) {
        VALUE inspected = rb_obj_as_string(rb_inspect(argv[i]));
        rb_uninterruptible(rb_p_write, inspected);
    }
    return rb_p_result(argc, argv);
}

Для каждого объекта obj выполняет:

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

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

Примеры:

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

Вывод:

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

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

pretty_inspect () Показать исходный код
# File lib/pp.rb, line 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 $_.
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; сообщение должно быть объектом, преобразуемым в строку, или 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));
}

Если вызвать rand без аргумента или если max.to_i.abs == 0, метод возвращает псевдослучайное число с плавающей запятой от 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 задает, следует ли исключать разделители строк.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    VALUE timeout;
    struct select_args args;
    struct timeval timerec;
    int i;

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

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

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

Вызывает системный вызов select(2), который отслеживает несколько файловых дескрипторов и ожидает, пока один или несколько из них не будут готовы к выполнению какого-либо типа операции ввода-вывода.

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

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

Аргумент timeout — это числовой интервал ожидания в секундах (например, целое число или число с плавающей точкой).

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Наконец, разработчики ядра 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 следующим образом: при повторном согласовании SSL в OpenSSL::SSL::SSLSocket также следует перехватывать IO::WaitReadable.

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 — это одно из следующего:

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

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

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

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

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

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

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

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

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

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

        if (!NIL_P(v)) {
            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, а также возвращаемое значение зависят от платформы.

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

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

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

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

    last_status_clear(th);

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

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

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

        if (data->error != 0) {
            if (eargp->exception) {
                VALUE command = eargp->invoke.sh.shell_script;
                RB_GC_GUARD(execarg_obj);
                rb_syserr_fail_str(data->error, command);
            }
            else {
                return Qnil;
            }
        }
        else if (eargp->exception) {
            VALUE command = eargp->invoke.sh.shell_script;
            VALUE str = rb_str_new_cstr("Command failed with");
            rb_str_cat_cstr(pst_message_status(str, data->status), ": ");
            rb_str_append(str, command);
            RB_GC_GUARD(execarg_obj);
            rb_exc_raise(rb_exc_new_str(rb_eRuntimeError, str));
        }
        else {
            return Qfalse;
        }

        RB_GC_GUARD(status);
    }

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

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

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

  • Запускает исполняемый файл по пути exe_path.

При вызове с недоверенными данными этот метод может создавать уязвимости безопасности; см. Инъекция команд.

Возвращает:

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

  • false, если статус завершения — ненулевое целое число.

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

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

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

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

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

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

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

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

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

Аргумент command_line

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

system('if true; then echo "Foo"; fi')          # => true  # Shell reserved word.
system('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 — это одно из следующего:

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

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

Пример:

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' Принадлежит ли сущность эффективному uid вызывающего процесса.
    'O' Как 'o', но используется реальный uid (а не эффективный uid).
    'p' Является ли сущность устройством FIFO (именованным каналом).
    'r' Доступна ли сущность для чтения с эффективными uid/gid вызывающего процесса.
    'R' Как 'r', но используются реальные uid/gid (а не эффективные uid/gid).
    'S' Является ли сущность сокетом.
    'u' Установлен ли бит setuid для сущности.
    'w' Доступна ли сущность для записи с эффективными uid/gid вызывающего процесса.
    'W' Как 'w', но используются реальные uid/gid (а не эффективные uid/gid).
    'x' Доступна ли сущность для выполнения с эффективными uid/gid вызывающего процесса.
    'X' Как 'x', но используются реальные uid/gid (а не эффективные uid/gid).
    '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, если для tag нет блока catch. Необязательный второй параметр задаёт возвращаемое значение блока 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
untrace_var(symbol [, cmd] ) → array or nil Показать исходный код
static VALUE
f_untrace_var(int c, const VALUE *a, VALUE _)
{
    return rb_f_untrace_var(c, a);
}

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

warn(*msgs, uplevel: nil, category: nil) → nil Показать исходный код
# File warning.rb, line 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, перед строкой добавляется информация для указанного кадра вызывающего кода в том же формате, который используется функцией C rb_warn.

# 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. Документацию см. в разделах generate и parse.

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

Возвращает объект URI, созданный на основе заданного uri, которым может быть строка URI или существующий объект URI:

# Returns a new URI.
uri = URI('http://github.com/ruby/ruby')
# => #<URI::HTTP http://github.com/ruby/ruby>
# Returns the given URI.
URI(uri)
# => #<URI::HTTP http://github.com/ruby/ruby>
gem (gem_name, *requirements) Показать исходный код
# File lib/rubygems/core_ext/kernel_gem.rb, line 35
def gem(gem_name, *requirements) # :doc:
  skip_list = (ENV["GEM_SKIP"] || "").split(/:/)
  raise Gem::LoadError, "skipping #{gem_name}" if skip_list.include? gem_name

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

    requirements = gem_name.requirement
    gem_name = gem_name.name
  end

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

  loaded = Gem.loaded_specs[gem_name]

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

  spec = dep.to_spec

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

Используйте Kernel#gem, чтобы активировать определенную версию gem_name.

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

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

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

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

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

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

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

Пример:

GEM_SKIP=libA:libB ruby -I../libA -I../libB ./mycode.rb
j (*objs) Показать исходный код
# File ext/json/lib/json/common.rb, line 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 заменяется нашей реализацией, которая умеет загружать гемы по требованию.

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

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

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

Сохраняется стандартное поведение require: если файл уже был загружен, возвращается false.

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

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

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

Spec-Zone.ru

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