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)
{
VALUE bindval, binding_self = Qundef;
rb_binding_t *bind;
const rb_proc_t *proc;
const rb_iseq_t *iseq = NULL;
const struct rb_block *block;
const rb_env_t *env = NULL;
GetProcPtr(self, proc);
block = &proc->block;
again:
switch (vm_block_type(block)) {
case block_type_iseq:
iseq = block->as.captured.code.iseq;
binding_self = block->as.captured.self;
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
break;
case block_type_proc:
GetProcPtr(block->as.proc, proc);
block = &proc->block;
goto again;
case block_type_symbol:
goto error;
case block_type_ifunc:
{
const struct vm_ifunc *ifunc = block->as.captured.code.ifunc;
if (IS_METHOD_PROC_IFUNC(ifunc)) {
VALUE method = (VALUE)ifunc->data;
binding_self = method_receiver(method);
iseq = rb_method_iseq(method);
env = VM_ENV_ENVVAL_PTR(block->as.captured.ep);
env = env_clone(env, method_cref(method));
/* set empty iseq */
RB_OBJ_WRITE(env, &env->iseq, rb_iseq_new(NULL, rb_str_new2("<empty iseq>"), rb_str_new2("<empty_iseq>"), Qnil, 0, ISEQ_TYPE_TOP));
break;
}
else {
error:
rb_raise(rb_eArgError, "Can't create Binding from C level Proc");
return Qnil;
}
}
}
bindval = rb_binding_alloc(rb_cBinding);
GetBindingPtr(bindval, bind);
bind->block.as.captured.self = binding_self;
bind->block.as.captured.code.iseq = env->iseq;
bind->block.as.captured.ep = env->ep;
if (iseq) {
rb_iseq_check(iseq);
bind->path = iseq->body->location.path;
bind->first_lineno = FIX2INT(rb_iseq_first_lineno(iseq));
}
else {
bind->path = Qnil;
bind->first_lineno = 0;
}
return bindval;
}