Spec-Zone.ru › Ruby 2.6

класс Binding

Родитель:
Объект

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

Эти объекты связывания могут быть переданы в качестве второго аргумента метода 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(строка [, имя_файла [,номер_строки]]) → обх Показать исходный код
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 в строке в контексте связывания. Если присутствуют необязательные параметры имя_файла и номер_строки, они будут использоваться при сообщении об ошибках синтаксиса.

def get_binding(param)
  binding
end
b = get_binding("hello")
b.eval("param")   #=> "hello"
irb() Показать исходный код
# File lib/irb.rb, line 792
def irb
  IRB.setup(eval("__FILE__"), argv: [])
  workspace = IRB::WorkSpace.new(self)
  STDOUT.print(workspace.code_around_binding)
  IRB::Irb.new(workspace).run(IRB.conf)
end

Открывает сеанс IRB, где вызывается binding.irb, что позволяет проводить интерактивную отладку. Вы можете вызывать любые методы или переменные, доступные в текущем объёме, и изменять состояние, если это необходимо.

Предположим, у вас есть файл Ruby под названием potato.rb с кодом:

class Potato
  def initialize
    @cooked = false
    binding.irb
    puts "Cooked potato: #{@cooked}"
  end
end

Potato.new

Запуск +ruby potato.rb+ откроет сеанс IRB, где вызовется binding.irb, и вы увидите следующее:

$ ruby potato.rb

From: potato.rb @ line 4 :

    1: class Potato
    2:   def initialize
    3:     @cooked = false
 => 4:     binding.irb
    5:     puts "Cooked potato: #{@cooked}"
    6:   end
    7: end
    8:
    9: Potato.new

irb(#<Potato:0x00007feea1916670>):001:0>

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

irb(#<Potato:0x00007feea1916670>):001:0> @cooked
=> false
irb(#<Potato:0x00007feea1916670>):002:0> self.class
=> Potato
irb(#<Potato:0x00007feea1916670>):003:0> caller.first
=> ".../2.5.1/lib/ruby/2.5.0/irb/workspace.rb:85:in `eval'"
irb(#<Potato:0x00007feea1916670>):004:0> @cooked = true
=> true

Вы можете выйти из сеанса IRB с помощью команды `exit`. Обратите внимание, что выход возобновит выполнение с точки, где binding.irb приостановил его, как видно из вывода, выведенного в стандартный вывод в этом примере:

irb(#<Potato:0x00007feea1916670>):005:0> exit
Cooked potato: true

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

local_variable_defined?(символ) → 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;

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    return get_local_variable_ptr(&env, lid) ? Qtrue : Qfalse;
}

Возвращает 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(символ) → 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;

    GetBindingPtr(bindval, bind);

    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    if ((ptr = get_local_variable_ptr(&env, lid)) == NULL) {
        sym = ID2SYM(lid);
      undefined:
        rb_name_err_raise("local variable `%1$s' is not defined for %2$s",
                          bindval, sym);
    }

    return *ptr;
}

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

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

Этот метод эквивалентен следующему коду:

binding.eval("#{symbol}")
local_variable_set(символ, обх) → обх Показать исходный код
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);

    GetBindingPtr(bindval, bind);
    env = VM_ENV_ENVVAL_PTR(vm_block_ep(&bind->block));
    if ((ptr = get_local_variable_ptr(&env, lid)) == 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));
    }

    RB_OBJ_WRITE(env, ptr, val);

    return val;
}

Set локальную переменную с именем 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 → Массив Показать исходный код
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 → объект Показать исходный код
static VALUE
bind_receiver(VALUE bindval)
{
    const rb_binding_t *bind;
    GetBindingPtr(bindval, bind);
    return vm_block_self(&bind->block);
}

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

source_location → [Строка, Целое число] Показать исходный код
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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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