Is there any difference in how class_eval & instance_eval work except def? Inside class_eval block def defines method to class itself (i.e. instance method) and inside instance_eval def defines method to the eigenclass of the class (i.e. class method). AFAIK all other features work identically in both cases (e.g. define_method, attr_accessor, class << self; end, defining constants). Is it true?
Answer is: def, undef and alias have different contexts for class_eval and instance_eval.
Long story short:
Object.instance_eval &blocksets:selftoObjectObject.singleton_classObject.class_eval &blocksets:selftoObjectObjectThe "current class" is used for
def,undefandalias, as well as constant and class variable lookups.Now, let's have a look at the implementation details.
Here's how
module_evalandinstance_evalare implemented in C:Both call
specific_eval, which takes the following arguments:int argc,VALUE *argv,VALUE klassandVALUE self.Note that:
module_evalpasses theModuleorClassinstance as bothklassandselfinstance_evalpasses the object's singleton class asklassIf given a block,
specific_evalwill callyield_under, which takes the following arguments:VALUE under,VALUE selfandVALUE values.There are two important lines in
yield_under:block.self = self;This sets the
selfof the block to the receiver.cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);The
crefis a linked list which specifies the "current class", which is used fordef,undefandalias, as well as constant and class variable lookups.That line basically sets the
creftounder.Finally:
When called from
module_eval,underwill be theClassorModuleinstance.When called from
instance_eval,underwill be the singleton class ofself.