SingletonClass* SingletonClass::attach(STATE, Object* obj, Class* sup) { SingletonClass *sc; sc = state->memory()->new_object_enduring<SingletonClass>(state, G(klass)); sc->init(state); sc->attached_instance(state, obj); sc->setup(state); if(kind_of<PackedObject>(obj)) { sc->set_type_info(state->memory()->type_info[Object::type]); } else { sc->set_type_info(obj->klass()->type_info()); } sc->set_packed_size(obj->klass()->packed_size()); sc->packed_ivar_info(state, obj->klass()->packed_ivar_info()); /* The superclass hierarchy for singleton classes lives in parallel to * that of classes. This code ensures that the superclasses of singleton * classes are also singleton classes. */ if(SingletonClass* already_sc = try_as<SingletonClass>(obj)) { /* If we are attaching a singleton class to something that is already a * SingletonClass, make the singleton class's superclass be the attachee's * superclass. klass and superclass are both singleton classes in this * case. */ sc->klass(state, sc); Class* super = already_sc->true_superclass(state)->singleton_class_instance(state); sc->superclass(state, super); super->track_subclass(state, sc); } else { /* If we are attaching to anything but a SingletonClass, the new * singleton class's class is the same as its superclass. This is where * the superclass chains for singleton and non-singleton classes * diverge. If no superclass argument was provided, we use the klass we * are replacing. */ if(!sup) { sup = obj->klass(); } /* Tell the new SingletonClass about the attachee's existing hierarchy */ Class* super_klass = Class::real_class(state, sup)->klass(); sc->klass(state, super_klass); sc->superclass(state, sup); sup->track_subclass(state, sc); } /* Finally, attach the new SingletonClass */ obj->klass(state, sc); return sc; }
void SingletonClass::Info::show(STATE, Object* self, int level) { SingletonClass* cls = as<SingletonClass>(self); Module* mod = try_as<Module>(cls->attached_instance()); const char* name; if(mod) { name = mod->name()->nil_p() ? "<anonymous>" : mod->name()->c_str(state); } else { name = "<some object>"; } std::cout << "#<SingletonClass:" << self->class_object(state)->name()->c_str(state) << " " << name << ":" << (void*)self << ">" << std::endl; }