In short:
Object.instance_eval &block sets:Object.class_eval &block sets:self to Object- "Current class" for
Object
The "current class" is used for def , undef and alias , as well as to search for class constants and variables.
Now let's look at the implementation details.
Here's how module_eval and instance_eval in C:
VALUE rb_mod_module_eval(int argc, VALUE *argv, VALUE mod) { return specific_eval(argc, argv, mod, mod); } VALUE rb_obj_instance_eval(int argc, VALUE *argv, VALUE self) { VALUE klass; if (SPECIAL_CONST_P(self)) { klass = Qnil; } else { klass = rb_singleton_class(self); } return specific_eval(argc, argv, klass, self); }
Both call specific_eval , which takes the following arguments: int argc , VALUE *argv , VALUE klass and VALUE self .
Note that:
module_eval passes an instance of Module or Class as klass and selfinstance_eval passes a singleton class object as klass
If a block is specified, specific_eval will call yield_under , which takes the following arguments: VALUE under , VALUE self and VALUE values .
if (rb_block_given_p()) { rb_check_arity(argc, 0, 0); return yield_under(klass, self, Qundef); }
There are two important lines in yield_under :
block.self = self;
This sets the self part of the block to the receiver.
cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
cref is a linked list that defines the "current class", which is used for def , undef and alias , as well as to search for class constants and variables.
This line basically sets cref under .
Finally:
When called from module_eval , under will be an instance of Class or Module .
When called from instance_eval , under will be a single self class.
Matheus moreira
source share