Beispiel #1
0
static void add_module(VALUE self, VALUE module)
{
    VALUE super = RCLASS_SUPER(rb_singleton_class(self));

#ifdef RUBY_19
    VALUE klass = class_alloc(T_ICLASS, rb_cClass);
#else
    NEWOBJ(klass, struct RClass);
    OBJSETUP(klass, rb_cClass, T_ICLASS);
#endif

    if (BUILTIN_TYPE(module) == T_ICLASS) {
        module = KLASS_OF(module);
    }
    if (!RCLASS_IV_TBL(module)) {
        RCLASS_IV_TBL(module) = (void*)st_init_numtable();
    }

    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
    RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
    RCLASS_SUPER(klass) = super;

    if (TYPE(module) == T_ICLASS) {
        KLASS_OF(klass) = KLASS_OF(module);
    } else {
        KLASS_OF(klass) = module;
    }
    OBJ_INFECT(klass, module);
    OBJ_INFECT(klass, super);

    RCLASS_SUPER(rb_singleton_class(self)) = (VALUE)klass;
}
Beispiel #2
0
static VALUE rb_unmix(VALUE self, VALUE module)
{
    VALUE klass;

    /* check that module is valid */
    if (TYPE(module) != T_MODULE)
        rb_raise(rb_eArgError, "error: parameter must be a module");

    for (klass = KLASS_OF(self); klass != rb_class_real(klass); klass = RCLASS_SUPER(klass)) {
        VALUE super = RCLASS_SUPER(klass);
        if (BUILTIN_TYPE(super) == T_ICLASS) {
            if (KLASS_OF(super) == module) {
                if (RCLASS_SUPER(module) && BUILTIN_TYPE(RCLASS_SUPER(module)) == T_ICLASS)
                    remove_nested_module(super, module);

                RCLASS_SUPER(klass) = RCLASS_SUPER(RCLASS_SUPER(klass));
                rb_clear_cache();

                /* If the module is taken out, call the unmixed(obj) hook on
                 * the module */
                rb_funcall(module, rb_intern("unmixed"), 1, self);

            }
        }
    }
    return self;
}
Beispiel #3
0
static void remove_nested_module(VALUE klass, VALUE include_class)
{
    if (KLASS_OF(RCLASS_SUPER(klass)) != KLASS_OF(RCLASS_SUPER(include_class))) {
        return;
    }
    if (RCLASS_SUPER(RCLASS_SUPER(include_class)) && BUILTIN_TYPE(RCLASS_SUPER(include_class)) == T_ICLASS) {
        remove_nested_module(RCLASS_SUPER(klass), RCLASS_SUPER(include_class));
    }
    RCLASS_SUPER(klass) = RCLASS_SUPER(RCLASS_SUPER(klass));
}
Beispiel #4
0
VALUE
rb_to_module(VALUE self)
{
    VALUE rclass, chain_start, jcur, klass;

    switch(BUILTIN_TYPE(self)) {
    case T_MODULE:
        return self;
    case T_CLASS:
        klass = self;
        break;
    case T_OBJECT:
    default:
        klass = rb_singleton_class(self);            
    }
            
    chain_start = j_class_new(klass, rb_cObject);

    KLASS_OF(chain_start) = rb_cModule;
    RBASIC(chain_start)->flags = T_MODULE;

    jcur = chain_start;
    for(rclass = RCLASS_SUPER(klass); rclass != rb_cObject;
        rclass = RCLASS_SUPER(rclass)) {
                
        RCLASS_SUPER(jcur) = j_class_new(rclass, rb_cObject);
        jcur = RCLASS_SUPER(jcur);
    }

    RCLASS_SUPER(jcur) = (VALUE)NULL;

    return chain_start;
}
Beispiel #5
0
/* a modified version of include_class_new from class.c */
static VALUE
j_class_new(VALUE module, VALUE sup)
{

#ifdef RUBY_19
    VALUE klass = class_alloc(T_ICLASS, rb_cClass);
#else
    NEWOBJ(klass, struct RClass);
    OBJSETUP(klass, rb_cClass, T_ICLASS);
#endif

    if (BUILTIN_TYPE(module) == T_ICLASS) {
        module = KLASS_OF(module);
    }

    if (!RCLASS_IV_TBL(module)) {

        RCLASS_IV_TBL(module) = (struct st_table *)st_init_numtable();
    }

    /* assign iv_tbl, m_tbl and super */
    RCLASS_IV_TBL(klass) = RCLASS_IV_TBL(module);
    RCLASS_SUPER(klass) = sup;
    if(TYPE(module) != T_OBJECT) {

        RCLASS_M_TBL(klass) = RCLASS_M_TBL(module);
    }
    else {
        RCLASS_M_TBL(klass) = RCLASS_M_TBL(CLASS_OF(module));
    }

    /* */

    if (TYPE(module) == T_ICLASS) {
        KLASS_OF(klass) = KLASS_OF(module);
    }
    else {
        KLASS_OF(klass) = module;
    }

    if(TYPE(module) != T_OBJECT) {
        OBJ_INFECT(klass, module);
        OBJ_INFECT(klass, sup);
    }
    return (VALUE)klass;
}