class Binding - Documentation for Ruby 4.0
Description: class Binding: Objects of class Binding encapsulate the execution context at some particular place in the code and retain this context for future use. code>, and pos
Keywords: ruby,class,Binding

🔍

No recent searches

# class Binding

Objects of class `Binding` encapsulate the execution context at some particular place in the code and retain this context for future use. The variables, methods, value of `self`, and possibly an iterator block that can be accessed in this context are all retained. `Binding` objects can be created using `Kernel#binding`, and are made available to the callback of `Kernel#set_trace_func` and instances of `TracePoint`.

These binding objects can be passed as the second argument of the `Kernel#eval` method, establishing an environment for the evaluation.

    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` objects have no class-specific methods.

### Public Instance Methods

eval(string [, filename [,lineno]]) → obj
Source

    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 */);
    }

Evaluates the Ruby expression(s) in string, in the binding’s context. If the optional filename and lineno parameters are present, they will be used when reporting syntax errors.

    def get_binding(param)
      binding
    end
    b = get_binding("hello")
    b.eval("param")   #=> "hello"

implicit_parameter_defined?(symbol) → obj
Source

    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));
    }

Returns `true` if the numbered parameter or “it” parameter exists.

    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
Source

    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);
    }

Returns the value of the numbered parameter or “it” parameter.

    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
Source

    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);
    }

Returns the names of numbered parameters and “it” parameter that are defined in the binding.

    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
Source

    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));
    }

Returns `true` if a local variable `symbol` exists.

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

This method is the short version of the following code:

    binding.eval("defined?(#{symbol}) == 'local-variable'")

local_variable_get(symbol) → obj
Source

    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);
    }

Returns the value of the local variable `symbol`.

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

This method is the short version of the following code:

    binding.eval("#{symbol}")

local_variable_set(symbol, obj) → obj
Source

    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;
    }

Set local variable named `symbol` as `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

This method behaves similarly to the following code:

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

if `obj` can be dumped in Ruby code.

local_variables → Array
Source

    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);
    }

Returns the names of the binding’s local variables as symbols.

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

This method is the short version of the following code:

    binding.eval("local_variables")

receiver → object
Source

    static VALUE
    bind_receiver(VALUE bindval)
    {
        const rb_binding_t *bind;
        GetBindingPtr(bindval, bind);
        return vm_block_self(&bind->block);
    }

Returns the bound receiver of the binding object.

source_location → [String, Integer]
Source

    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);
    }

Returns the Ruby source filename and line number of the binding object.