VALUE rb_singleton_class(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } DEFER_INTS; if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_iv_get(RBASIC(obj)->klass, "__attached__") == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); ALLOW_INTS; return klass; }
VALUE rb_singleton_class(VALUE obj) { if (FIXNUM_P(obj) || SYMBOL_P(obj) || FIXFLOAT_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } VALUE klass; switch (TYPE(obj)) { case T_CLASS: case T_MODULE: // FIXME we should really create a new metaclass here. klass = *(VALUE *)obj; break; default: klass = rb_make_metaclass(obj, RBASIC(obj)->klass); break; } return klass; }
static inline VALUE special_singleton_class_of(VALUE obj) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); return Qnil; }
VALUE rb_singleton_class(VALUE obj) { VALUE klass; ID attached; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %ld", obj); } CONST_ID(attached, "__attached__"); if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (BUILTIN_TYPE(obj) == T_CLASS) { if (rb_iv_get(RBASIC(klass)->klass, "__attached__") != klass) make_metametaclass(klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }
/*! * \internal * Returns the singleton class of \a obj. Creates it if necessary. * * \note DO NOT expose the returned singleton class to * outside of class.c. * Use \ref rb_singleton_class instead for * consistency of the metaclass hierarchy. */ static VALUE singleton_class_of(VALUE obj) { VALUE klass; if (FIXNUM_P(obj) || SYMBOL_P(obj)) { rb_raise(rb_eTypeError, "can't define singleton"); } if (rb_special_const_p(obj)) { SPECIAL_SINGLETON(Qnil, rb_cNilClass); SPECIAL_SINGLETON(Qfalse, rb_cFalseClass); SPECIAL_SINGLETON(Qtrue, rb_cTrueClass); rb_bug("unknown immediate %p", (void *)obj); } if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON) && rb_ivar_get(RBASIC(obj)->klass, id_attached) == obj) { klass = RBASIC(obj)->klass; } else { klass = rb_make_metaclass(obj, RBASIC(obj)->klass); } if (OBJ_TAINTED(obj)) { OBJ_TAINT(klass); } else { FL_UNSET(klass, FL_TAINT); } if (OBJ_UNTRUSTED(obj)) { OBJ_UNTRUST(klass); } else { FL_UNSET(klass, FL_UNTRUSTED); } if (OBJ_FROZEN(obj)) OBJ_FREEZE(klass); return klass; }