binding()
public
Returns the binding associated with
prc. Note that Kernel#eval accepts
either a Proc or a Binding object as its second parameter.
def fred(param)
proc {}
end
b = fred(99)
eval("param", b.binding)
Show source
static VALUE
proc_binding(VALUE self)
{
rb_proc_t *proc;
VALUE bindval, envval;
rb_binding_t *bind;
rb_iseq_t *iseq;
GetProcPtr(self, proc);
envval = proc->envval;
iseq = proc->block.iseq;
if (RUBY_VM_IFUNC_P(iseq)) {
rb_env_t *env;
if (!IS_METHOD_PROC_NODE((NODE *)iseq)) {
rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
}
iseq = rb_method_get_iseq(RNODE(iseq)->u2.value);
GetEnvPtr(envval, env);
if (iseq && env->local_size < iseq->local_size) {
int prev_local_size = env->local_size;
int local_size = iseq->local_size;
VALUE newenvval = TypedData_Wrap_Struct(RBASIC_CLASS(envval), RTYPEDDATA_TYPE(envval), 0);
rb_env_t *newenv = xmalloc(sizeof(rb_env_t) + ((local_size + 1) * sizeof(VALUE)));
RTYPEDDATA_DATA(newenvval) = newenv;
newenv->env_size = local_size + 2;
newenv->local_size = local_size;
newenv->prev_envval = env->prev_envval;
newenv->block = env->block;
MEMCPY(newenv->env, env->env, VALUE, prev_local_size + 1);
rb_mem_clear(newenv->env + prev_local_size + 1, local_size - prev_local_size);
newenv->env[local_size + 1] = newenvval;
envval = newenvval;
}
}
bindval = rb_binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->env = envval;
bind->blockprocval = proc->blockprocval;
if (RUBY_VM_NORMAL_ISEQ_P(iseq)) {
bind->path = iseq->location.path;
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq->self));
}
else {
bind->path = Qnil;
bind->first_lineno = 0;
}
return bindval;
}