diff --git a/class.c b/class.c index d0f91528b4..d2dd43815c 100644 --- a/class.c +++ b/class.c @@ -225,13 +225,6 @@ rb_class_boot(VALUE super) return (VALUE)klass; } - -/*! - * Ensures a class can be derived from super. - * - * \param super a reference to an object. - * \exception TypeError if \a super is not a Class or \a super is a singleton class. - */ void rb_check_inheritable(VALUE super) { @@ -247,13 +240,6 @@ rb_check_inheritable(VALUE 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) { @@ -684,17 +670,6 @@ rb_make_metaclass(VALUE obj, VALUE unused) } } - -/*! - * Defines a new class. - * \param id ignored - * \param super A class from which the new class will derive. NULL means \c Object class. - * \return the created class - * \throw TypeError if super is not a \c Class object. - * - * \note the returned class will not be associated with \a id. - * You must explicitly set a class name if necessary. - */ VALUE rb_define_class_id(ID id, VALUE super) { @@ -763,24 +738,6 @@ rb_define_class_under(VALUE outer, const char *name, VALUE super) return rb_define_class_id_under(outer, rb_intern(name), super); } - -/*! - * Defines a class under the namespace of \a outer. - * \param outer a class which contains the new class. - * \param id name of the new class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw TypeError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - * \note the compaction GC does not move classes returned by this function. - */ VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super) { @@ -1851,23 +1808,6 @@ rb_singleton_class_get(VALUE obj) return klass; } -/*! - * Returns the singleton class of \a obj. Creates it if necessary. - * - * \param obj an arbitrary object. - * \throw TypeError if \a obj is an Integer or a Symbol. - * \return the singleton class. - * - * \post \a obj has its own singleton class. - * \post if \a obj is a class, - * the returned singleton class also has its own - * singleton class in order to keep consistency of the - * inheritance structure of metaclasses. - * \note a new singleton class will be created - * if \a obj does not have it. - * \note the singleton classes for nil, true and false are: - * NilClass, TrueClass and FalseClass. - */ VALUE rb_singleton_class(VALUE obj) { @@ -1891,13 +1831,6 @@ rb_singleton_class(VALUE obj) #ifdef rb_define_singleton_method #undef rb_define_singleton_method #endif -/*! - * Defines a singleton method for \a obj. - * \param obj an arbitrary object - * \param name name of the singleton method - * \param func the method body - * \param argc the number of parameters, or -1 or -2. see \ref defmethod. - */ void rb_define_singleton_method(VALUE obj, const char *name, VALUE (*func)(ANYARGS), int argc) { diff --git a/include/ruby/internal/intern/class.h b/include/ruby/internal/intern/class.h index d80fd9739e..af0c0768b8 100644 --- a/include/ruby/internal/intern/class.h +++ b/include/ruby/internal/intern/class.h @@ -27,30 +27,321 @@ RBIMPL_SYMBOL_EXPORT_BEGIN() /* class.c */ -VALUE rb_class_new(VALUE); -VALUE rb_mod_init_copy(VALUE, VALUE); -VALUE rb_singleton_class_clone(VALUE); -void rb_singleton_class_attached(VALUE,VALUE); -void rb_check_inheritable(VALUE); -VALUE rb_define_class_id(ID, VALUE); -VALUE rb_define_class_id_under(VALUE, ID, VALUE); + +/** + * Creates a new, anonymous class. + * + * @param[in] super What would become a parent class. + * @exception rb_eTypeError `super` is not something inheritable. + * @return An anonymous class that inherits `super`. + */ +VALUE rb_class_new(VALUE super); + +/** + * The comment that comes with this function says `:nodoc:`. Not sure what + * that means though. + * + * @param[out] clone Destination object. + * @param[in] orig Source object. + * @exception rb_eTypeError Cannot copy `orig`. + * @return The passed `clone`. + */ +VALUE rb_mod_init_copy(VALUE clone, VALUE orig); + +/** + * Asserts that the given class can derive a child class. A class might or + * might not be able to do so; for instance a singleton class cannot. + * + * @param[in] super Possible super class. + * @exception rb_eTypeError No it cannot. + * @post Upon successful return `super` can derive. + */ +void rb_check_inheritable(VALUE super); + +/** + * This is a very badly designed API that creates an anonymous class. + * + * @param[in] id Discarded for no reason (why...). + * @param[in] super What would become a parent class. 0 means + * ::rb_cObject. + * @exception rb_eTypeError `super` is not something inheritable. + * @return An anonymous class that inherits `super`. + * @warning You must explicitly name the return value. + */ +VALUE rb_define_class_id(ID id, VALUE super); + +/** + * Identical to rb_define_class_under(), except it takes the name in ::ID + * instead of C's string. + * + * @param[out] outer A class which contains the new class. + * @param[in] id Name of the new class + * @param[in] super A class from which the new class will derive. + * 0 means ::rb_cObject. + * @exception rb_eTypeError The constant name `id` is already taken but the + * constant is not a class. + * @exception rb_eTypeError The class is already defined but the class can + * not be reopened because its superclass is not + * `super`. + * @exception rb_eArgError `super` is NULL. + * @return The created class. + * @post `outer::id` refers the returned class. + * @note If a class named `id` is already defined and its superclass is + * `super`, the function just returns the defined class. + * @note The compaction GC does not move classes returned by this + * function. + */ +VALUE rb_define_class_id_under(VALUE outer, ID id, VALUE super); + +/** + * Creates a new, anonymous module. + * + * @return An anonymous module. + */ VALUE rb_module_new(void); -VALUE rb_define_module_id(ID); -VALUE rb_define_module_id_under(VALUE, ID); -VALUE rb_mod_included_modules(VALUE); -VALUE rb_mod_include_p(VALUE, VALUE); -VALUE rb_mod_ancestors(VALUE); -VALUE rb_class_instance_methods(int, const VALUE*, VALUE); -VALUE rb_class_public_instance_methods(int, const VALUE*, VALUE); -VALUE rb_class_protected_instance_methods(int, const VALUE*, VALUE); -VALUE rb_class_private_instance_methods(int, const VALUE*, VALUE); -VALUE rb_obj_singleton_methods(int, const VALUE*, VALUE); -void rb_define_method_id(VALUE, ID, VALUE (*)(ANYARGS), int); -void rb_undef(VALUE, ID); -void rb_define_protected_method(VALUE, const char*, VALUE (*)(ANYARGS), int); -void rb_define_private_method(VALUE, const char*, VALUE (*)(ANYARGS), int); -void rb_define_singleton_method(VALUE, const char*, VALUE(*)(ANYARGS), int); -VALUE rb_singleton_class(VALUE); + +/** + * This is a very badly designed API that creates an anonymous module. + * + * @param[in] id Discarded for no reason (why...). + * @return An anonymous module. + * @warning You must explicitly name the return value. + */ +VALUE rb_define_module_id(ID id); + +/** + * Identical to rb_define_module_under(), except it takes the name in ::ID + * instead of C's string. + * + * @param[out] outer A class which contains the new module. + * @param[in] id Name of the new module + * @exception rb_eTypeError The constant name `id` is already taken but the + * constant is not a module. + * @return The created module. + * @post `outer::id` refers the returned module. + * @note The compaction GC does not move classes returned by this + * function. + */ +VALUE rb_define_module_id_under(VALUE outer, ID id); + +/** + * Queries the list of included modules. It can also be seen as a routine to + * first call rb_mod_ancestors(), then rejects non-modules from the return + * value. + * + * @param[in] mod Class or Module. + * @return An array of modules that are either included or prepended in any + * of `mod`'s ancestry tree (including itself). + */ +VALUE rb_mod_included_modules(VALUE mod); + +/** + * Queries if the passed module is included by the module. It can also be seen + * as a routine to first call rb_mod_included_modules(), then see if the return + * value contains the passed module. + * + * @param[in] child A Module. + * @param[in] parent Another Module. + * @exception rb_eTypeError `child` is not an instance of ::rb_cModule. + * @retval RUBY_Qtrue `parent` is either included or prepended in any + * of `child`'s ancestry tree (including itself). + * @return RUBY_Qfalse Otherwise. + */ +VALUE rb_mod_include_p(VALUE child, VALUE parent); + +/** + * Queries the module's ancestors. This routine gathers classes and modules + * that the passed module either inherits, includes, or prepends, then + * recursively applies that routine again and again to the collected entries + * until the list doesn't grow up. + * + * @param[in] mod A module or a class. + * @return An array of classes or modules that `mod` possibly recursively + * inherits, includes, or prepends. + * + * @internal + * + * Above description is written in a recursive language but in practice it + * computes the return value iteratively. + */ +VALUE rb_mod_ancestors(VALUE mod); + +/** + * Generates an array of symbols, which are the list of method names defined in + * the passed class. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Array of at most one object, which controls (if + * any) whether the return array includes the names + * of methods defined in ancestors or not. + * @param[in] mod A module or a class. + * @exception rb_eArgError `argc` out of range. + * @return An array of symbols collecting names of instance methods that + * are not private, defined at `mod`. + */ +VALUE rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod); + +/** + * Identical to rb_class_instance_methods(), except it returns names of methods + * that are public only. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Array of at most one object, which controls (if + * any) whether the return array includes the names + * of methods defined in ancestors or not. + * @param[in] mod A module or a class. + * @exception rb_eArgError `argc` out of range. + * @return An array of symbols collecting names of instance methods that + * are public, defined at `mod`. + */ +VALUE rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod); + +/** + * Identical to rb_class_instance_methods(), except it returns names of methods + * that are protected only. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Array of at most one object, which controls (if + * any) whether the return array includes the names + * of methods defined in ancestors or not. + * @param[in] mod A module or a class. + * @exception rb_eArgError `argc` out of range. + * @return An array of symbols collecting names of instance methods that + * are protected, defined at `mod`. + */ +VALUE rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod); + +/** + * Identical to rb_class_instance_methods(), except it returns names of methods + * that are private only. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Array of at most one object, which controls (if + * any) whether the return array includes the names + * of methods defined in ancestors or not. + * @param[in] mod A module or a class. + * @exception rb_eArgError `argc` out of range. + * @return An array of symbols collecting names of instance methods that + * are protected, defined at `mod`. + */ +VALUE rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod); + +/** + * Identical to rb_class_instance_methods(), except it returns names of + * singleton methods instead of instance methods. + * + * @param[in] argc Number of objects of `argv`. + * @param[in] argv Array of at most one object, which controls (if + * any) whether the return array includes the names + * of methods defined in ancestors or not. + * @param[in] obj Arbitrary ruby object. + * @exception rb_eArgError `argc` out of range. + * @return An array of symbols collecting names of instance methods that + * are not private, defined at the singleton class of `obj`. + */ +VALUE rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj); + +/** + * Identical to rb_define_method(), except it takes the name of the method in + * ::ID instead of C's string. + * + * @param[out] klass A module or a class. + * @param[in] mid Name of the function. + * @param[in] func The method body. + * @param[in] arity The number of parameters. See @ref defmethod. + * @note There are in fact 18 different prototypes for func. + * @see ::ruby::backward::cxxanyargs::define_method::rb_define_method_id + */ +void rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int arity); + +/* vm_method.c */ + +/** + * Inserts a method entry that hides previous method definition of the given + * name. This is not a deletion of a method. Method of the same name defined + * in a parent class is kept invisible in this way. + * + * @param[out] mod The module to insert an undef. + * @param[in] mid Name of the undef. + * @exception rb_eTypeError `klass` is a non-module. + * @exception rb_eFrozenError `klass` is frozen. + * @exception rb_eNameError No such method named `klass#name`. + * @post `klass#name` is undefined. + * @see rb_undef_method + * + * @internal + * + * @shyouhei doesn't understand why this is not the ::ID -taking variant of + * rb_undef_method(), given rb_remove_method() has its ::ID -taking counterpart + * named rb_remove_method_id(). + */ +void rb_undef(VALUE mod, ID mid); + +/* class.c */ + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_define_method(), except it defines a protected method. + * + * @param[out] klass A module or a class. + * @param[in] mid Name of the function. + * @param[in] func The method body. + * @param[in] arity The number of parameters. See @ref defmethod. + * @note There are in fact 18 different prototypes for func. + * @see ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method + */ +void rb_define_protected_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_define_method(), except it defines a private method. + * + * @param[out] klass A module or a class. + * @param[in] mid Name of the function. + * @param[in] func The method body. + * @param[in] arity The number of parameters. See @ref defmethod. + * @note There are in fact 18 different prototypes for func. + * @see ::ruby::backward::cxxanyargs::define_method::rb_define_protected_method + */ +void rb_define_private_method(VALUE klass, const char *mid, VALUE (*func)(ANYARGS), int arity); + +RBIMPL_ATTR_NONNULL(()) +/** + * Identical to rb_define_method(), except it defines a singleton method. + * + * @param[out] obj Arbitrary ruby object. + * @param[in] mid Name of the function. + * @param[in] func The method body. + * @param[in] arity The number of parameters. See @ref defmethod. + * @note There are in fact 18 different prototypes for func. + * @see ::ruby::backward::cxxanyargs::define_method::rb_define_singleton_method + */ +void rb_define_singleton_method(VALUE obj, const char *mid, VALUE(*func)(ANYARGS), int arity); + +/** + * Finds or creates the singleton class of the passed object. + * + * @param[out] obj Arbitrary ruby object. + * @exception rb_eTypeError `obj` cannot have its singleton class. + * @return A (possibly newly allocated) instance of ::rb_cClass. + * @post `obj` has its singleton class, which is the return value. + * @post In case `obj` is a class, the returned singleton class also has + * its own singleton class in order to keep consistency of the + * inheritance structure of metaclasses. + * @note A new singleton class will be created if `obj` did not have + * one. + * @note The singleton classes for ::RUBY_Qnil, ::RUBY_Qtrue, and + * ::RUBY_Qfalse are ::rb_cNilClass, ::rb_cTrueClass, and + * ::rb_cFalseClass respectively. + * + * @internal + * + * You can _create_ a singleton class of a frozen object. Intentional or ...? + * + * Nowadays there are wider range of objects who cannot have singleton classes + * than before. For instance some string instances cannot for some reason. + */ +VALUE rb_singleton_class(VALUE obj); RBIMPL_SYMBOL_EXPORT_END()