Spec-Zone.ru › Ruby 4.0

class Binding

Родительский класс:
Object

Объекты класса Binding инкапсулируют контекст выполнения в определённом месте кода и сохраняют его для дальнейшего использования. В этом контексте сохраняются переменные, методы, значение self и, возможно, блок итератора, к которым можно получить доступ. Объекты Binding можно создавать с помощью Kernel#binding; они также доступны в обратном вызове Kernel#set_trace_func и экземплярах TracePoint.

Эти объекты привязки можно передать в качестве второго аргумента метода Kernel#eval, задав среду для вычисления.

class Demo
  def initialize(n)
    @secret = n
  end
  def get_binding
    binding
  end
end

k1 = Demo.new(99)
b1 = k1.get_binding
k2 = Demo.new(-3)
b2 = k2.get_binding

eval("@secret", b1)   #=> 99
eval("@secret", b2)   #=> -3
eval("@secret")       #=> nil

Объекты Binding не имеют методов, специфичных для класса.

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

eval(string [, filename [,lineno]]) → obj Показать исходный код
static VALUE
bind_eval(int argc, VALUE *argv, VALUE bindval)
{
    VALUE args[4];

    rb_scan_args(argc, argv, "12", &args[0], &args[2], &args[3]);
    args[1] = bindval;
    return rb_f_eval(argc+1, args, Qnil /* self will be searched in eval */);
}

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

def get_binding(param)
  binding
end
b = get_binding("hello")
b.eval("param")   #=> "hello"
implicit_parameter_defined?(symbol) → obj Показать исходный код
static VALUE
bind_implicit_parameter_defined_p(VALUE bindval, VALUE sym)
{
    ID lid = check_local_id(bindval, &sym);
    const rb_binding_t *bind;
    const rb_env_t *env;

    if (lid == idIt) lid = idItImplicit;

    if (!lid || !rb_implicit_param_p(lid)) {
        rb_name_err_raise("'%1$s' is not an implicit parameter",
                          bindval, sym);
    }

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    return RBOOL(get_local_variable_ptr(&env, lid, FALSE));
}

Возвращает true, если существует параметр с номером или параметр «it».

def foo
  [42].each do
    it
    binding.implicit_parameter_defined?(:it) #=> true
    binding.implicit_parameter_defined?(:_1) #=> false
  end

  { k: 42 }.each do
    _2
    binding.implicit_parameter_defined?(:_1) #=> true
    binding.implicit_parameter_defined?(:_2) #=> true
    binding.implicit_parameter_defined?(:_3) #=> false
    binding.implicit_parameter_defined?(:it) #=> false
  end
end
implicit_parameter_get(symbol) → obj Показать исходный код
static VALUE
bind_implicit_parameter_get(VALUE bindval, VALUE sym)
{
    ID lid = check_local_id(bindval, &sym);
    const rb_binding_t *bind;
    const VALUE *ptr;
    const rb_env_t *env;

    if (lid == idIt) lid = idItImplicit;

    if (!lid || !rb_implicit_param_p(lid)) {
        rb_name_err_raise("'%1$s' is not an implicit parameter",
                          bindval, sym);
    }

    GetBindingPtr(bindval, bind);

    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    if ((ptr = get_local_variable_ptr(&env, lid, FALSE)) != NULL) {
        return *ptr;
    }

    if (lid == idItImplicit) lid = idIt;
    rb_name_err_raise("implicit parameter '%1$s' is not defined for %2$s", bindval, ID2SYM(lid));
    UNREACHABLE_RETURN(Qundef);
}

Возвращает значение параметра с номером или параметра «it».

def foo
  [42].each do
    it
    binding.implicit_parameter_get(:it) #=> 42
  end

  { k: 42 }.each do
    _2
    binding.implicit_parameter_get(:_1) #=> :k
    binding.implicit_parameter_get(:_2) #=> 42
  end
end
implicit_parameters → Array Показать исходный код
static VALUE
bind_implicit_parameters(VALUE bindval)
{
    const rb_binding_t *bind;
    const rb_env_t *env;

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));

    if (get_local_variable_ptr(&env, idItImplicit, FALSE)) {
        return rb_ary_new_from_args(1, ID2SYM(idIt));
    }

    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    return rb_vm_env_numbered_parameters(env);
}

Возвращает имена параметров с номерами и параметра «it», определённых в привязке.

def foo
  [42].each do
    it
    binding.implicit_parameters #=> [:it]
  end

  { k: 42 }.each do
    _2
    binding.implicit_parameters #=> [:_1, :_2]
  end
end
local_variable_defined?(symbol) → obj Показать исходный код
static VALUE
bind_local_variable_defined_p(VALUE bindval, VALUE sym)
{
    ID lid = check_local_id(bindval, &sym);
    const rb_binding_t *bind;
    const rb_env_t *env;

    if (!lid) return Qfalse;
    if (rb_numparam_id_p(lid)) {
        rb_name_err_raise("numbered parameter '%1$s' is not a local variable",
                          bindval, ID2SYM(lid));
    }

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    return RBOOL(get_local_variable_ptr(&env, lid, TRUE));
}

Возвращает true, если существует локальная переменная symbol.

def foo
  a = 1
  binding.local_variable_defined?(:a) #=> true
  binding.local_variable_defined?(:b) #=> false
end

Этот метод представляет собой краткую версию следующего кода:

binding.eval("defined?(#{symbol}) == 'local-variable'")
local_variable_get(symbol) → obj Показать исходный код
static VALUE
bind_local_variable_get(VALUE bindval, VALUE sym)
{
    ID lid = check_local_id(bindval, &sym);
    const rb_binding_t *bind;
    const VALUE *ptr;
    const rb_env_t *env;

    if (!lid) goto undefined;
    if (rb_numparam_id_p(lid)) {
        rb_name_err_raise("numbered parameter '%1$s' is not a local variable",
                          bindval, ID2SYM(lid));
    }

    GetBindingPtr(bindval, bind);

    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    if ((ptr = get_local_variable_ptr(&env, lid, TRUE)) != NULL) {
        return *ptr;
    }

    sym = ID2SYM(lid);
  undefined:
    rb_name_err_raise("local variable '%1$s' is not defined for %2$s",
                      bindval, sym);
    UNREACHABLE_RETURN(Qundef);
}

Возвращает значение локальной переменной symbol.

def foo
  a = 1
  binding.local_variable_get(:a) #=> 1
  binding.local_variable_get(:b) #=> NameError
end

Этот метод представляет собой краткую версию следующего кода:

binding.eval("#{symbol}")
local_variable_set(symbol, obj) → obj Показать исходный код
static VALUE
bind_local_variable_set(VALUE bindval, VALUE sym, VALUE val)
{
    ID lid = check_local_id(bindval, &sym);
    rb_binding_t *bind;
    const VALUE *ptr;
    const rb_env_t *env;

    if (!lid) lid = rb_intern_str(sym);
    if (rb_numparam_id_p(lid)) {
        rb_name_err_raise("numbered parameter '%1$s' is not a local variable",
                          bindval, ID2SYM(lid));
    }

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    if ((ptr = get_local_variable_ptr(&env, lid, TRUE)) == NULL) {
        /* not found. create new env */
        ptr = rb_binding_add_dynavars(bindval, bind, 1, &lid);
        env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    }

#if YJIT_STATS
    rb_yjit_collect_binding_set();
#endif

    RB_OBJ_WRITE(env, ptr, val);

    return val;
}

Устанавливает локальную переменную с именем symbol в значение obj.

def foo
  a = 1
  bind = binding
  bind.local_variable_set(:a, 2) # set existing local variable `a'
  bind.local_variable_set(:b, 3) # create new local variable `b'
                                 # `b' exists only in binding

  p bind.local_variable_get(:a)  #=> 2
  p bind.local_variable_get(:b)  #=> 3
  p a                            #=> 2
  p b                            #=> NameError
end

Этот метод работает аналогично следующему коду:

binding.eval("#{symbol} = #{obj}")

если obj можно представить в виде кода Ruby.

local_variables → Array Показать исходный код
static VALUE
bind_local_variables(VALUE bindval)
{
    const rb_binding_t *bind;
    const rb_env_t *env;

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    return rb_vm_env_local_variables(env);
}

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

def foo
  a = 1
  2.times do |n|
    binding.local_variables #=> [:a, :n]
  end
end

Этот метод представляет собой краткую версию следующего кода:

binding.eval("local_variables")
receiver → object Показать исходный код
static VALUE
bind_receiver(VALUE bindval)
{
    const rb_binding_t *bind;
    GetBindingPtr(bindval, bind);
    return vm_block_self(&bind->block);
}

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

source_location → [String, Integer] Показать исходный код
static VALUE
bind_location(VALUE bindval)
{
    VALUE loc[2];
    const rb_binding_t *bind;
    GetBindingPtr(bindval, bind);
    loc[0] = pathobj_path(bind->pathobj);
    loc[1] = INT2FIX(bind->first_lineno);

    return rb_ary_new4(2, loc);
}

Возвращает имя файла исходного кода Ruby и номер строки объекта привязки.

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