Короче:
Object.instance_eval &block
sets:
Object.class_eval &block
sets:
self
to Object
- «Текущий класс» на
Object
«Текущий класс» используется для def
, undef
и alias
, а также для поиска констант и переменных класса.
Теперь давайте посмотрим на детали реализации.
Вот как module_eval
и _ 13_ реализованы на 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);
}
Оба вызывают specific_eval
, который принимает следующие аргументы: int argc
, VALUE *argv
, VALUE klass
и VALUE self
.
Обратите внимание, что:
module_eval
передает экземпляр Module
или Class
как klass
и self
instance_eval
передает одноэлементный класс объекта как klass
Если задан блок, specific_eval
вызовет yield_under
, что займет следующие аргументы: VALUE under
, VALUE self
и VALUE values
.
if (rb_block_given_p()) {
rb_check_arity(argc, 0, 0);
return yield_under(klass, self, Qundef);
}
В yield_under
есть две важные строки:
block.self = self;
Это устанавливает self
блока на приемник.
cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr);
cref
- это связанный список, в котором указывается "текущий class ", который используется для def
, undef
и alias
, а также для поиска констант и переменных класса.
Эта строка в основном устанавливает cref
в under
.
Наконец-то:
person
Matheus Moreira
schedule
24.04.2012