/*! * Creates a meta^(n+1)-class for a meta^(n)-class. * \param metaclass a class of a class * \return the created meta^(n+1)-class. * \pre \a metaclass is a metaclass * \post the class of \a metaclass is the returned class. */ static VALUE make_metametaclass(VALUE metaclass) { VALUE metametaclass, super_of_metaclass; if (RBASIC(metaclass)->klass == metaclass) { /* for meta^(n)-class of Class */ metametaclass = rb_class_boot(Qnil); RBASIC(metametaclass)->klass = metametaclass; } else { metametaclass = rb_class_boot(Qnil); RBASIC(metametaclass)->klass = (RBASIC(RBASIC(metaclass)->klass)->klass == RBASIC(metaclass)->klass) ? make_metametaclass(RBASIC(metaclass)->klass) : RBASIC(RBASIC(metaclass)->klass)->klass; } FL_SET(metametaclass, FL_SINGLETON); rb_singleton_class_attached(metametaclass, metaclass); RBASIC(metaclass)->klass = metametaclass; super_of_metaclass = RCLASS_SUPER(metaclass); while (FL_TEST(super_of_metaclass, T_ICLASS)) { super_of_metaclass = RCLASS_SUPER(super_of_metaclass); } RCLASS_SUPER(metametaclass) = rb_iv_get(RBASIC(super_of_metaclass)->klass, "__attached__") == super_of_metaclass ? RBASIC(super_of_metaclass)->klass : make_metametaclass(super_of_metaclass); OBJ_INFECT(metametaclass, RCLASS_SUPER(metametaclass)); return metametaclass; }
void Init_with_ext() { VALUE super = rb_class_boot(0); rb_cCallWith = rb_class_boot(super); rb_name_class(rb_cCallWith, rb_intern("CallWith")); rb_const_set(rb_cObject, rb_intern("CallWith"), rb_cCallWith); rb_global_variable(&rb_cCallWith); rb_undef_alloc_func(rb_cCallWith); rb_define_singleton_method(rb_cCallWith, "create", callwith_s_create, 2); rb_define_method(rb_cCallWith, "__instance_eval__", rb_obj_instance_eval, -1); rb_define_method(rb_cCallWith, "__callwith__obj__", callwith_obj, 0); rb_define_method(rb_cCallWith, "__callwith__self_obj__", callwith_self_obj, 0); rb_define_method(rb_cCallWith, "__callwith__cleanup__", callwith_cleanup, 0); }
/*! * Creates a metaclass of \a klass * \param klass a class * \return created metaclass for the class * \pre \a klass is a Class object * \pre \a klass has no singleton class. * \post the class of \a klass is the returned class. * \post the returned class is meta^(n+1)-class when \a klass is a meta^(n)-klass for n >= 0 */ static inline VALUE make_metaclass(VALUE klass) { VALUE super; VALUE metaclass = rb_class_boot(Qundef); FL_SET(metaclass, FL_SINGLETON); rb_singleton_class_attached(metaclass, klass); if (META_CLASS_OF_CLASS_CLASS_P(klass)) { METACLASS_OF(klass) = METACLASS_OF(metaclass) = metaclass; } else { VALUE tmp = METACLASS_OF(klass); /* for a meta^(n)-class klass, tmp is meta^(n)-class of Class class */ METACLASS_OF(klass) = metaclass; METACLASS_OF(metaclass) = ENSURE_EIGENCLASS(tmp); } super = RCLASS_SUPER(klass); while (RB_TYPE_P(super, T_ICLASS)) super = RCLASS_SUPER(super); RCLASS_SUPER(metaclass) = super ? ENSURE_EIGENCLASS(super) : rb_cClass; OBJ_INFECT(metaclass, RCLASS_SUPER(metaclass)); return metaclass; }
/*! * Creates a new class. * \param super a class from which the new class derives. * \exception TypeError \a super is not inheritable. * \exception TypeError \a super is the Class class. */ VALUE rb_class_new(VALUE super) { Check_Type(super, T_CLASS); rb_check_inheritable(super); return rb_class_boot(super); }
/*! * Creates a new class. * \param super a class from which the new class derives. * \exception TypeError \a super is not inheritable. * \exception TypeError \a super is the Class class. */ VALUE rb_class_new(VALUE super) { Check_Type(super, T_CLASS); rb_check_inheritable(super); if (super == rb_cClass) { rb_raise(rb_eTypeError, "can't make subclass of Class"); } return rb_class_boot(super); }
static VALUE boot_defclass(const char *name, VALUE super) { VALUE obj = rb_class_boot(super); ID id = rb_intern(name); rb_name_class(obj, id); rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); return obj; }
static VALUE boot_defclass(const char *name, VALUE super) { extern st_table *rb_class_tbl; VALUE obj = rb_class_boot(super); ID id = rb_intern(name); rb_name_class(obj, id); st_add_direct(rb_class_tbl, id, obj); rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); return obj; }
VALUE rb_class_new(VALUE super) { Check_Type(super, T_CLASS); if (super == rb_cClass) { rb_raise(rb_eTypeError, "can't make subclass of Class"); } if (FL_TEST(super, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't make subclass of virtual class"); } return rb_class_boot(super); }
/*! * Creates a singleton class for \a obj. * \pre \a obj must not a immediate nor a special const. * \pre \a obj must not a Class object. * \pre \a obj has no singleton class. */ static inline VALUE make_singleton_class(VALUE obj) { VALUE orig_class = RBASIC(obj)->klass; VALUE klass = rb_class_boot(orig_class); FL_SET(klass, FL_SINGLETON); RBASIC(obj)->klass = klass; rb_singleton_class_attached(klass, obj); METACLASS_OF(klass) = METACLASS_OF(rb_class_real(orig_class)); return klass; }
/*! * \internal * Creates a singleton class for an object. * * \note DO NOT USE the function in an extension libraries. Use rb_singleton_class. * \param obj An object. * \param super A class from which the singleton class derives. * \note \a super is ignored if \a obj is a metaclass. * \return The singleton class of the object. */ VALUE rb_make_metaclass(VALUE obj, VALUE super) { if (BUILTIN_TYPE(obj) == T_CLASS && FL_TEST(obj, FL_SINGLETON)) { /* obj is a metaclass */ return make_metametaclass(obj); } else { VALUE metasuper; VALUE klass = rb_class_boot(super); FL_SET(klass, FL_SINGLETON); RBASIC(obj)->klass = klass; rb_singleton_class_attached(klass, obj); metasuper = RBASIC(rb_class_real(super))->klass; /* metaclass of a superclass may be NULL at boot time */ if (metasuper) { RBASIC(klass)->klass = metasuper; } return klass; } }
/* * call-seq: * Module.load(String) => Module * * Load a module from a string. */ static VALUE module_load(VALUE klass, VALUE str) { VALUE arr, class_name, metaclass_str, metaclass, superclass_name, included_modules, class_variables_str, class_variables, instance_methods_str, instance_methods, flags, module; if( rb_safe_level() >= 4 || (rb_safe_level() >= 1 && OBJ_TAINTED(str))) { /* no playing with knives in the sandbox */ rb_raise(rb_eSecurityError, "Insecure: can't load module"); } arr = marshal_load(str); class_name = rb_ary_pop(arr); metaclass_str = rb_ary_pop(arr); superclass_name = rb_ary_pop(arr); included_modules = rb_ary_pop(arr); class_variables_str = rb_ary_pop(arr); instance_methods_str = rb_ary_pop(arr); flags = rb_ary_pop(arr); if(RTEST(superclass_name)) { VALUE superclass; rb_check_type(superclass_name, T_STRING); superclass = rb_funcall( lookup_module_proc, rb_intern("call"), 1, superclass_name); #if RUBY_VERSION_CODE >= 180 /* Can't make subclass of Class on 1.8.x */ module = rb_class_boot(superclass); rb_define_alloc_func(module, module_instance_allocate); #else module = rb_class_new(superclass); #endif } else { module = rb_module_new(); } if(!NIL_P(class_name)) { VALUE outer_module = rb_funcall(outer_module_proc, rb_intern("call"), 1, class_name); VALUE module_name = rb_funcall(module_name_proc, rb_intern("call"), 1, class_name); rb_const_set(outer_module, SYM2ID(module_name), module); } RBASIC(module)->flags = NUM2INT(flags); include_modules(module, included_modules); class_variables = marshal_load(class_variables_str); add_class_variables(module, class_variables); instance_methods = marshal_load(instance_methods_str); add_methods(module, instance_methods); metaclass = marshal_load(metaclass_str); if(RTEST(metaclass)) { rb_singleton_class_attached(metaclass, module); RBASIC(module)->klass = metaclass; } return module; }