Class: Module
Instance Method Summary collapse
-
#include_between(mod) {|p, c| ... } ⇒ Object
Walks the receiver’s super chain, yielding the previous and current entries in the super chain at every step.
-
#swap_method_tables(other) ⇒ self
Swap the method table of the receiver with the method table of the given class or module.
-
#to_class(klass = Object) ⇒ Class
Makes a copy of the module, converts the copy to a class, and returns it.
-
#uninclude(mod) ⇒ Object
Unincludes the given module
mod
from the receiver or any of the receiver’s ancestors.
Instance Method Details
#include_between(mod) {|p, c| ... } ⇒ Object
Walks the receiver’s super chain, yielding the previous and current entries in the super chain at every step. The first time the block returns true
, mod
is inserted into the super chain between the two values, and the method returns immediately. Raises TypeError
if mod
is not a Module. If the block ever returns true
, the return value is mod
. If the block never returns true
, the return value is nil
. On the first block call, the first block argument is the receiver, and on the last block call, the last block argument is nil
.
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 |
# File 'ext/evilr/evilr.c', line 519
static VALUE evilr_include_between(VALUE klass, VALUE mod) {
VALUE iclass, prev, cur;
evilr__check_immediate(mod);
evilr__check_type(T_MODULE, mod);
/* Create ICLASS for module by inserting it and removing it.
* If module already in super chain, will change it's position. */
rb_include_module(klass, mod);
iclass = evilr__iclass_matching(klass, mod);
evilr_uninclude(klass, mod);
for (prev = klass, cur = RCLASS_SUPER(klass); prev ; prev = cur, cur = cur ? RCLASS_SUPER(cur) : cur) {
if (BUILTIN_TYPE(prev) == T_CLASS) {
rb_clear_cache_by_class(prev);
}
if (rb_yield_values(2, INCLUDE_BETWEEN_VAL(prev), INCLUDE_BETWEEN_VAL(cur)) == Qtrue) {
RCLASS_SET_SUPER(prev, iclass);
RCLASS_SET_SUPER(iclass, cur);
return mod;
}
}
return Qnil;
}
|
#swap_method_tables(other) ⇒ self
Swap the method table of the receiver with the method table of the given class or module. If other
is not a class or module, raise a TypeError
.
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 |
# File 'ext/evilr/evilr.c', line 373
static VALUE evilr_swap_method_tables(VALUE self, VALUE other) {
struct st_table *tmp;
evilr__check_immediate(other);
if(BUILTIN_TYPE(other) != T_MODULE && BUILTIN_TYPE(other) != T_CLASS) {
rb_raise(rb_eTypeError, "non-class or module used");
}
tmp = RCLASS_M_TBL(self);
RCLASS(self)->m_tbl = RCLASS_M_TBL(other);
RCLASS(other)->m_tbl = tmp;
rb_clear_cache_by_class(self);
rb_clear_cache_by_class(other);
return self;
}
|
#to_class(klass = Object) ⇒ Class
Makes a copy of the module, converts the copy to a class, and returns it. The returned class can then have instances created from it. The klass
argument sets the superclass of the returned class. If klass
is not a Class, raises TypeError
.
768 769 770 771 772 773 774 775 776 777 |
# File 'ext/evilr/evilr.c', line 768
static VALUE evilr_to_class(int argc, VALUE *argv, VALUE self) {
VALUE klass = evilr__optional_class(argc, argv);
self = rb_obj_clone(self);
RBASIC_SET_KLASS(self, rb_singleton_class(klass));
RCLASS_SET_SUPER(self, klass);
FL_UNSET(self, T_MASK);
FL_SET(self, T_CLASS);
return self;
}
|
#uninclude(mod) ⇒ Object
Unincludes the given module mod
from the receiver or any of the receiver’s ancestors. Walks the super chain of the receiver, and if an iclass for mod
is encountered, the super chain is modified to skip that iclass. Returns mod
if an iclass for mod was present in the super chain, and nil
otherwise. If mod
is not a Module, a TypeError
is raised.
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 |
# File 'ext/evilr/evilr.c', line 463
static VALUE evilr_uninclude(VALUE klass, VALUE mod) {
VALUE cur, prev;
evilr__check_immediate(mod);
evilr__check_type(T_MODULE, mod);
for (prev = klass, cur = RCLASS_SUPER(klass); cur ; prev = cur, cur = RCLASS_SUPER(cur)) {
if (BUILTIN_TYPE(prev) == T_CLASS) {
rb_clear_cache_by_class(prev);
}
if (BUILTIN_TYPE(cur) == T_ICLASS && RBASIC_KLASS(cur) == mod) {
RCLASS_SET_SUPER(prev, RCLASS_SUPER(cur));
return mod;
}
}
return Qnil;
}
|