Skip to content

Instantly share code, notes, and snippets.

@methodmissing
Created June 12, 2009 09:33
Show Gist options
  • Select an option

  • Save methodmissing/128542 to your computer and use it in GitHub Desktop.

Select an option

Save methodmissing/128542 to your computer and use it in GitHub Desktop.
void
rb_include_module(klass, module)
VALUE klass, module;
{
VALUE p, c;
int changed = 0;
rb_frozen_class_p(klass);
if (!OBJ_TAINTED(klass)) {
rb_secure(4);
}
if (TYPE(module) != T_MODULE) {
Check_Type(module, T_MODULE);
}
OBJ_INFECT(klass, module);
c = klass;
while (module) {
int superclass_seen = Qfalse;
if (RCLASS(klass)->m_tbl == RCLASS(module)->m_tbl)
rb_raise(rb_eArgError, "cyclic include detected");
/* ignore if the module included already in superclasses */
for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
switch (BUILTIN_TYPE(p)) {
case T_ICLASS:
if (RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
if (!superclass_seen) {
c = p; /* move insertion point */
}
goto skip;
}
break;
case T_CLASS:
superclass_seen = Qtrue;
break;
}
}
c = RCLASS(c)->super = include_class_new(module, RCLASS(c)->super);
changed = 1;
skip:
module = RCLASS(module)->super;
}
if (changed) rb_clear_cache();
}
void
rb_clear_cache()
{
struct cache_entry *ent, *end;
if (!ruby_running) return;
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
ent->mid = 0;
ent++;
}
}
void
rb_extend_object(obj, module)
VALUE obj, module;
{
rb_include_module(rb_singleton_class(obj), module);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment