/*
* call-seq:
* remove_features(mod) => mod
*
* When this module is unincluded from another, Nodewrap calls
* remove_features in this module. The default behavior is to remove
* the constants, methods, and module variables of this module from
* _mod_. If this module has not been included by _mod_, an exception
* will be raised.
*/
static VALUE module_remove_features(VALUE module, VALUE uninclude)
{
VALUE prev, mod;
if(TYPE(uninclude) != T_CLASS && TYPE(uninclude) != T_MODULE)
{
Check_Type(uninclude, T_CLASS);
}
rb_frozen_class_p(uninclude);
if(!OBJ_TAINTED(uninclude))
{
rb_secure(4);
}
OBJ_INFECT(uninclude, module);
if(RCLASS(uninclude)->m_tbl == RCLASS(module)->m_tbl)
{
rb_raise(rb_eArgError, "Cannot remove module from itself");
}
prev = uninclude;
mod = RCLASS_SUPER(uninclude);
while(mod)
{
if(RCLASS(module)->m_tbl == RCLASS(mod)->m_tbl)
{
RCLASS_SUPER(prev) = RCLASS_SUPER(mod);
rb_clear_cache();
return module;
}
if(BUILTIN_TYPE(mod) == T_CLASS)
{
break;
}
prev = mod;
mod = RCLASS_SUPER(mod);
}
rb_raise(rb_eArgError, "Could not find included module");
return module;
}