class Module

A Module is a collection of methods and constants. The methods in a module may be instance methods or module methods. Instance methods appear as methods in a class when the module is included, module methods do not. Conversely, module methods may be called without creating an encapsulating object, while instance methods may not. (SeeModule#module_function.)

In the descriptions that follow, the parametersym refers to a symbol, which is either a quoted string or aSymbol (such as:name).

moduleModincludeMathCONST =1defmeth#  ...endendMod.class#=> ModuleMod.constants#=> [:CONST, :PI, :E]Mod.instance_methods#=> [:meth]

Public Class Methods

Source
static VALUErb_mod_s_constants(int argc, VALUE *argv, VALUE mod){    const rb_cref_t *cref = rb_vm_cref();    VALUE klass;    VALUE cbase = 0;    void *data = 0;    if (argc > 0 || mod != rb_cModule) {        return rb_mod_constants(argc, argv, mod);    }    while (cref) {        klass = CREF_CLASS(cref);        if (!CREF_PUSHED_BY_EVAL(cref) &&            !NIL_P(klass)) {            data = rb_mod_const_at(CREF_CLASS(cref), data);            if (!cbase) {                cbase = klass;            }        }        cref = CREF_NEXT(cref);    }    if (cbase) {        data = rb_mod_const_of(cbase, data);    }    return rb_const_list(data);}

In the first form, returns an array of the names of all constants accessible from the point of call. This list includes the names of all modules and classes defined in the global scope.

Module.constants.first(4)# => [:ARGF, :ARGV, :ArgumentError, :Array]Module.constants.include?(:SEEK_SET)# => falseclassIOModule.constants.include?(:SEEK_SET)# => trueend

The second form calls the instance methodconstants.

Source
static VALUErb_mod_nesting(VALUE _){    VALUE ary = rb_ary_new();    const rb_cref_t *cref = rb_vm_cref();    while (cref && CREF_NEXT(cref)) {        VALUE klass = CREF_CLASS(cref);        if (!CREF_PUSHED_BY_EVAL(cref) &&            !NIL_P(klass)) {            rb_ary_push(ary, klass);        }        cref = CREF_NEXT(cref);    }    return ary;}

Returns the list ofModules nested at the point of call.

moduleM1moduleM2$a =Module.nestingendend$a#=> [M1::M2, M1]$a[0].name#=> "M1::M2"
Source
static VALUErb_mod_initialize(VALUE module){    return rb_mod_initialize_exec(module);}

Creates a new anonymous module. If a block is given, it is passed the module object, and the block is evaluated in the context of this module likemodule_eval.

fred =Module.newdodefmeth1"hello"enddefmeth2"bye"endenda ="my string"a.extend(fred)#=> "my string"a.meth1#=> "hello"a.meth2#=> "bye"

Assign the module to a constant (name starting uppercase) if you want to treat it like a regular module.

Source
static VALUErb_mod_s_used_modules(VALUE _){    const rb_cref_t *cref = rb_vm_cref();    VALUE ary = rb_ary_new();    while (cref) {        if (!NIL_P(CREF_REFINEMENTS(cref))) {            rb_hash_foreach(CREF_REFINEMENTS(cref), used_modules_i, ary);        }        cref = CREF_NEXT(cref);    }    return rb_funcall(ary, rb_intern("uniq"), 0);}

Returns an array of all modules used in the current scope. The ordering of modules in the resulting array is not defined.

moduleArefineObjectdoendendmoduleBrefineObjectdoendendusingAusingBpModule.used_modules

produces:

[B,A]
Source
static VALUErb_mod_s_used_refinements(VALUE _){    const rb_cref_t *cref = rb_vm_cref();    VALUE ary = rb_ary_new();    while (cref) {        if (!NIL_P(CREF_REFINEMENTS(cref))) {            rb_hash_foreach(CREF_REFINEMENTS(cref), used_refinements_i, ary);        }        cref = CREF_NEXT(cref);    }    return ary;}

Returns an array of all modules used in the current scope. The ordering of modules in the resulting array is not defined.

moduleArefineObjectdoendendmoduleBrefineObjectdoendendusingAusingBpModule.used_refinements

produces:

[#<refinement:Object@B>, #<refinement:Object@A>]

Public Instance Methods

Source
static VALUErb_mod_lt(VALUE mod, VALUE arg){    if (mod == arg) return Qfalse;    return rb_class_inherited_p(mod, arg);}

Returns true ifmod is a subclass ofother. Returnsfalse ifmod is the same asother ormod is an ancestor ofother. Returnsnil if there’s no relationship between the two. (Think of the relationship in terms of the class definition: “class A < B” implies “A < B”.)

Source
VALUErb_class_inherited_p(VALUE mod, VALUE arg){    if (mod == arg) return Qtrue;    if (RB_TYPE_P(arg, T_CLASS) && RB_TYPE_P(mod, T_CLASS)) {        // comparison between classes        size_t mod_depth = RCLASS_SUPERCLASS_DEPTH(mod);        size_t arg_depth = RCLASS_SUPERCLASS_DEPTH(arg);        if (arg_depth < mod_depth) {            // check if mod < arg            return RCLASS_SUPERCLASSES(mod)[arg_depth] == arg ?                Qtrue :                Qnil;        }        else if (arg_depth > mod_depth) {            // check if mod > arg            return RCLASS_SUPERCLASSES(arg)[mod_depth] == mod ?                Qfalse :                Qnil;        }        else {            // Depths match, and we know they aren't equal: no relation            return Qnil;        }    }    else {        if (!CLASS_OR_MODULE_P(arg) && !RB_TYPE_P(arg, T_ICLASS)) {            rb_raise(rb_eTypeError, "compared with non class/module");        }        if (class_search_ancestor(mod, RCLASS_ORIGIN(arg))) {            return Qtrue;        }        /* not mod < arg; check if mod > arg */        if (class_search_ancestor(arg, mod)) {            return Qfalse;        }        return Qnil;    }}

Returns true ifmod is a subclass ofother or is the same asother. Returnsnil if there’s no relationship between the two. (Think of the relationship in terms of the class definition: “class A < B” implies “A < B”.)

Source
static VALUErb_mod_cmp(VALUE mod, VALUE arg){    VALUE cmp;    if (mod == arg) return INT2FIX(0);    if (!CLASS_OR_MODULE_P(arg)) {        return Qnil;    }    cmp = rb_class_inherited_p(mod, arg);    if (NIL_P(cmp)) return Qnil;    if (cmp) {        return INT2FIX(-1);    }    return INT2FIX(1);}

Comparison—Returns -1, 0, +1 or nil depending on whethermodule includesother_module, they are the same, or ifmodule is included byother_module.

Returnsnil ifmodule has no relationship withother_module, ifother_module is not a module, or if the two values are incomparable.

Source
VALUErb_obj_equal(VALUE obj1, VALUE obj2){    return RBOOL(obj1 == obj2);}

Equality — At theObject level,== returnstrue only ifobj andother are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.

Unlike==, theequal? method should never be overridden by subclasses as it is used to determine object identity (that is,a.equal?(b) if and only ifa is the same object asb):

obj ="a"other =obj.dupobj==other#=> trueobj.equal?other#=> falseobj.equal?obj#=> true

Theeql? method returnstrue ifobj andother refer to the same hash key. This is used byHash to test members for equality. For any pair of objects whereeql? returnstrue, thehash value of both objects must be equal. So any subclass that overrideseql? should also overridehash appropriately.

For objects of classObject,eql? is synonymous with==. Subclasses normally continue this tradition by aliasingeql? to their overridden== method, but there are exceptions.Numeric types, for example, perform type conversion across==, but not acrosseql?, so:

1==1.0#=> true1.eql?1.0#=> false
Source
static VALUErb_mod_eqq(VALUE mod, VALUE arg){    return rb_obj_is_kind_of(arg, mod);}

Case Equality—Returnstrue ifobj is an instance ofmod or an instance of one ofmod’s descendants. Of limited use for modules, but can be used incase statements to classify objects by class.

Source
static VALUErb_mod_gt(VALUE mod, VALUE arg){    if (mod == arg) return Qfalse;    return rb_mod_ge(mod, arg);}

Returns true ifmod is an ancestor ofother. Returnsfalse ifmod is the same asother ormod is a descendant ofother. Returnsnil if there’s no relationship between the two. (Think of the relationship in terms of the class definition: “class A < B” implies “B > A”.)

Source
static VALUErb_mod_ge(VALUE mod, VALUE arg){    if (!CLASS_OR_MODULE_P(arg)) {        rb_raise(rb_eTypeError, "compared with non class/module");    }    return rb_class_inherited_p(arg, mod);}

Returns true ifmod is an ancestor ofother, or the two modules are the same. Returnsnil if there’s no relationship between the two. (Think of the relationship in terms of the class definition: “class A < B” implies “B > A”.)

Source
static VALUErb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname){    ID oldid = rb_check_id(&oldname);    if (!oldid) {        rb_print_undef_str(mod, oldname);    }    VALUE id = rb_to_id(newname);    rb_alias(mod, id, oldid);    return ID2SYM(id);}

Makesnew_name a new copy of the methodold_name. This can be used to retain access to methods that are overridden.

moduleModalias_method:orig_exit,:exit#=> :orig_exitdefexit(code=0)puts"Exiting with code #{code}"orig_exit(code)endendincludeModexit(99)

produces:

Exitingwithcode99
Source
VALUErb_mod_ancestors(VALUE mod){    VALUE p, ary = rb_ary_new();    VALUE refined_class = Qnil;    if (BUILTIN_TYPE(mod) == T_MODULE && FL_TEST(mod, RMODULE_IS_REFINEMENT)) {        refined_class = rb_refinement_module_get_refined_class(mod);    }    for (p = mod; p; p = RCLASS_SUPER(p)) {        if (p == refined_class) break;        if (p != RCLASS_ORIGIN(p)) continue;        if (BUILTIN_TYPE(p) == T_ICLASS) {            rb_ary_push(ary, METACLASS_OF(p));        }        else {            rb_ary_push(ary, p);        }    }    return ary;}

Returns a list of modules included/prepended inmod (includingmod itself).

moduleModincludeMathincludeComparableprependEnumerableendMod.ancestors#=> [Enumerable, Mod, Comparable, Math]Math.ancestors#=> [Math]Enumerable.ancestors#=> [Enumerable]
Source
VALUErb_mod_attr(int argc, VALUE *argv, VALUE klass){    if (argc == 2 && (argv[1] == Qtrue || argv[1] == Qfalse)) {        ID id = id_for_attr(klass, argv[0]);        VALUE names = rb_ary_new();        rb_category_warning(RB_WARN_CATEGORY_DEPRECATED, "optional boolean argument is obsoleted");        rb_attr(klass, id, 1, RTEST(argv[1]), TRUE);        rb_ary_push(names, ID2SYM(id));        if (argv[1] == Qtrue) rb_ary_push(names, ID2SYM(rb_id_attrset(id)));        return names;    }    return rb_mod_attr_reader(argc, argv, klass);}

The first form is equivalent toattr_reader. The second form is equivalent toattr_accessor(name) but deprecated. The last form is equivalent toattr_reader(name) but deprecated. Returns an array of defined method names as symbols.

Source
static VALUErb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass){    int i;    VALUE names = rb_ary_new2(argc * 2);    for (i=0; i<argc; i++) {        ID id = id_for_attr(klass, argv[i]);        rb_attr(klass, id, TRUE, TRUE, TRUE);        rb_ary_push(names, ID2SYM(id));        rb_ary_push(names, ID2SYM(rb_id_attrset(id)));    }    return names;}

Defines a named attribute for this module, where the name issymbol.id2name, creating an instance variable (@name) and a corresponding access method to read it. Also creates a method calledname= to set the attribute.String arguments are converted to symbols. Returns an array of defined method names as symbols.

moduleModattr_accessor(:one,:two)#=> [:one, :one=, :two, :two=]endMod.instance_methods.sort#=> [:one, :one=, :two, :two=]
Source
static VALUErb_mod_attr_reader(int argc, VALUE *argv, VALUE klass){    int i;    VALUE names = rb_ary_new2(argc);    for (i=0; i<argc; i++) {        ID id = id_for_attr(klass, argv[i]);        rb_attr(klass, id, TRUE, FALSE, TRUE);        rb_ary_push(names, ID2SYM(id));    }    return names;}

Creates instance variables and corresponding methods that return the value of each instance variable. Equivalent to calling “attr:name” on each name in turn.String arguments are converted to symbols. Returns an array of defined method names as symbols.

Source
static VALUErb_mod_attr_writer(int argc, VALUE *argv, VALUE klass){    int i;    VALUE names = rb_ary_new2(argc);    for (i=0; i<argc; i++) {        ID id = id_for_attr(klass, argv[i]);        rb_attr(klass, id, FALSE, TRUE, TRUE);        rb_ary_push(names, ID2SYM(rb_id_attrset(id)));    }    return names;}

Creates an accessor method to allow assignment to the attributesymbol.id2name.String arguments are converted to symbols. Returns an array of defined method names as symbols.

Source
static VALUErb_mod_autoload(VALUE mod, VALUE sym, VALUE file){    ID id = rb_to_id(sym);    FilePathValue(file);    rb_autoload_str(mod, id, file);    return Qnil;}

Registersfilename to be loaded (using Kernel::require) the first time thatconst (which may be aString or a symbol) is accessed in the namespace ofmod.

moduleAendA.autoload(:B,"b")A::B.doit# autoloads "b"

Ifconst inmod is defined as autoload, the file name to be loaded is replaced withfilename. Ifconst is defined but not as autoload, does nothing.

Files that are currently being loaded must not be registered for autoload.

Source
static VALUErb_mod_autoload_p(int argc, VALUE *argv, VALUE mod){    int recur = (rb_check_arity(argc, 1, 2) == 1) ? TRUE : RTEST(argv[1]);    VALUE sym = argv[0];    ID id = rb_check_id(&sym);    if (!id) {        return Qnil;    }    return rb_autoload_at_p(mod, id, recur);}

Returnsfilename to be loaded ifname is registered asautoload in the namespace ofmod or one of its ancestors.

moduleAendA.autoload(:B,"b")A.autoload?(:B)#=> "b"

Ifinherit is false, the lookup only checks the autoloads in the receiver:

classAautoload:CONST,"const.rb"endclassB<AendB.autoload?(:CONST)#=> "const.rb", found in A (ancestor)B.autoload?(:CONST,false)#=> nil, not found in B itself

Evaluates the string or block in the context ofmod, except that when a block is given, constant/class variable lookup is not affected. This can be used to add methods to a class.module_eval returns the result of evaluating its argument. The optionalfilename andlineno parameters set the text for error messages.

classThingenda =%q{def hello() "Hello there!" end}Thing.module_eval(a)putsThing.new.hello()Thing.module_eval("invalid code","dummy",123)

produces:

Hello there!dummy:123:in `module_eval': undefined local variable    or method `code' for Thing:Class
Alias for:module_eval

Evaluates the given block in the context of the class/module. The method defined in the block will belong to the receiver. Any arguments passed to the method will be passed to the block. This can be used if the block needs to access instance variables.

classThingendThing.class_exec{defhello()"Hello there!"end}putsThing.new.hello()

produces:

Hellothere!
Alias for:module_exec
Source
static VALUErb_mod_cvar_defined(VALUE obj, VALUE iv){    ID id = id_for_var(obj, iv, class);    if (!id) {        return Qfalse;    }    return rb_cvar_defined(obj, id);}

Returnstrue if the given class variable is defined inobj.String arguments are converted to symbols.

classFred@@foo =99endFred.class_variable_defined?(:@@foo)#=> trueFred.class_variable_defined?(:@@bar)#=> false
Source
static VALUErb_mod_cvar_get(VALUE obj, VALUE iv){    ID id = id_for_var(obj, iv, class);    if (!id) {        rb_name_err_raise("uninitialized class variable %1$s in %2$s",                          obj, iv);    }    return rb_cvar_get(obj, id);}

Returns the value of the given class variable (or throws aNameError exception). The@@ part of the variable name should be included for regular class variables.String arguments are converted to symbols.

classFred@@foo =99endFred.class_variable_get(:@@foo)#=> 99
Source
static VALUErb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val){    ID id = id_for_var(obj, iv, class);    if (!id) id = rb_intern_str(iv);    rb_cvar_set(obj, id, val);    return val;}

Sets the class variable named bysymbol to the given object. If the class variable name is passed as a string, that string is converted to a symbol.

classFred@@foo =99deffoo@@fooendendFred.class_variable_set(:@@foo,101)#=> 101Fred.new.foo#=> 101
Source
VALUErb_mod_class_variables(int argc, const VALUE *argv, VALUE mod){    bool inherit = true;    st_table *tbl;    if (rb_check_arity(argc, 0, 1)) inherit = RTEST(argv[0]);    if (inherit) {        tbl = mod_cvar_of(mod, 0);    }    else {        tbl = mod_cvar_at(mod, 0);    }    return cvar_list(tbl);}

Returns an array of the names of class variables inmod. This includes the names of class variables in any included modules, unless theinherit parameter is set tofalse.

classOne@@var1 =1endclassTwo<One@@var2 =2endOne.class_variables#=> [:@@var1]Two.class_variables#=> [:@@var2, :@@var1]Two.class_variables(false)#=> [:@@var2]
Source
static VALUErb_mod_const_defined(int argc, VALUE *argv, VALUE mod){    VALUE name, recur;    rb_encoding *enc;    const char *pbeg, *p, *path, *pend;    ID id;    rb_check_arity(argc, 1, 2);    name = argv[0];    recur = (argc == 1) ? Qtrue : argv[1];    if (SYMBOL_P(name)) {        if (!rb_is_const_sym(name)) goto wrong_name;        id = rb_check_id(&name);        if (!id) return Qfalse;        return RTEST(recur) ? rb_const_defined(mod, id) : rb_const_defined_at(mod, id);    }    path = StringValuePtr(name);    enc = rb_enc_get(name);    if (!rb_enc_asciicompat(enc)) {        rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");    }    pbeg = p = path;    pend = path + RSTRING_LEN(name);    if (p >= pend || !*p) {        goto wrong_name;    }    if (p + 2 < pend && p[0] == ':' && p[1] == ':') {        mod = rb_cObject;        p += 2;        pbeg = p;    }    while (p < pend) {        VALUE part;        long len, beglen;        while (p < pend && *p != ':') p++;        if (pbeg == p) goto wrong_name;        id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);        beglen = pbeg-path;        if (p < pend && p[0] == ':') {            if (p + 2 >= pend || p[1] != ':') goto wrong_name;            p += 2;            pbeg = p;        }        if (!id) {            part = rb_str_subseq(name, beglen, len);            OBJ_FREEZE(part);            if (!rb_is_const_name(part)) {                name = part;                goto wrong_name;            }            else {                return Qfalse;            }        }        if (!rb_is_const_id(id)) {            name = ID2SYM(id);            goto wrong_name;        }#if 0        mod = rb_const_search(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);        if (UNDEF_P(mod)) return Qfalse;#else        if (!RTEST(recur)) {            if (!rb_const_defined_at(mod, id))                return Qfalse;            if (p == pend) return Qtrue;            mod = rb_const_get_at(mod, id);        }        else if (beglen == 0) {            if (!rb_const_defined(mod, id))                return Qfalse;            if (p == pend) return Qtrue;            mod = rb_const_get(mod, id);        }        else {            if (!rb_const_defined_from(mod, id))                return Qfalse;            if (p == pend) return Qtrue;            mod = rb_const_get_from(mod, id);        }#endif        if (p < pend && !RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {            rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",                     QUOTE(name));        }    }    return Qtrue;  wrong_name:    rb_name_err_raise(wrong_constant_name, mod, name);    UNREACHABLE_RETURN(Qundef);}

Says whethermod or its ancestors have a constant with the given name:

Float.const_defined?(:EPSILON)#=> true, found in Float itselfFloat.const_defined?("String")#=> true, found in Object (ancestor)BasicObject.const_defined?(:Hash)#=> false

Ifmod is aModule, additionallyObject and its ancestors are checked:

Math.const_defined?(:String)#=> true, found in Object

In each of the checked classes or modules, if the constant is not present but there is an autoload for it,true is returned directly without autoloading:

moduleAdminautoload:User,'admin/user'endAdmin.const_defined?(:User)#=> true

If the constant is not found the callbackconst_missing isnot called and the method returnsfalse.

Ifinherit is false, the lookup only checks the constants in the receiver:

IO.const_defined?(:SYNC)#=> true, found in File::Constants (ancestor)IO.const_defined?(:SYNC,false)#=> false, not found in IO itself

In this case, the same logic for autoloading applies.

If the argument is not a valid constant name aNameError is raised with the message “wrong constant namename”:

Hash.const_defined?'foobar'#=> NameError: wrong constant name foobar
Source
static VALUErb_mod_const_get(int argc, VALUE *argv, VALUE mod){    VALUE name, recur;    rb_encoding *enc;    const char *pbeg, *p, *path, *pend;    ID id;    rb_check_arity(argc, 1, 2);    name = argv[0];    recur = (argc == 1) ? Qtrue : argv[1];    if (SYMBOL_P(name)) {        if (!rb_is_const_sym(name)) goto wrong_name;        id = rb_check_id(&name);        if (!id) return rb_const_missing(mod, name);        return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);    }    path = StringValuePtr(name);    enc = rb_enc_get(name);    if (!rb_enc_asciicompat(enc)) {        rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");    }    pbeg = p = path;    pend = path + RSTRING_LEN(name);    if (p >= pend || !*p) {        goto wrong_name;    }    if (p + 2 < pend && p[0] == ':' && p[1] == ':') {        mod = rb_cObject;        p += 2;        pbeg = p;    }    while (p < pend) {        VALUE part;        long len, beglen;        while (p < pend && *p != ':') p++;        if (pbeg == p) goto wrong_name;        id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);        beglen = pbeg-path;        if (p < pend && p[0] == ':') {            if (p + 2 >= pend || p[1] != ':') goto wrong_name;            p += 2;            pbeg = p;        }        if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {            rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",                     QUOTE(name));        }        if (!id) {            part = rb_str_subseq(name, beglen, len);            OBJ_FREEZE(part);            if (!rb_is_const_name(part)) {                name = part;                goto wrong_name;            }            else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) {                part = rb_str_intern(part);                mod = rb_const_missing(mod, part);                continue;            }            else {                rb_mod_const_missing(mod, part);            }        }        if (!rb_is_const_id(id)) {            name = ID2SYM(id);            goto wrong_name;        }#if 0        mod = rb_const_get_0(mod, id, beglen > 0 || !RTEST(recur), RTEST(recur), FALSE);#else        if (!RTEST(recur)) {            mod = rb_const_get_at(mod, id);        }        else if (beglen == 0) {            mod = rb_const_get(mod, id);        }        else {            mod = rb_const_get_from(mod, id);        }#endif    }    return mod;  wrong_name:    rb_name_err_raise(wrong_constant_name, mod, name);    UNREACHABLE_RETURN(Qundef);}

Checks for a constant with the given name inmod. Ifinherit is set, the lookup will also search the ancestors (andObject ifmod is aModule).

The value of the constant is returned if a definition is found, otherwise aNameError is raised.

Math.const_get(:PI)#=> 3.14159265358979

This method will recursively look up constant names if a namespaced class name is provided. For example:

moduleFoo;classBar;endendObject.const_get'Foo::Bar'

Theinherit flag is respected on each lookup. For example:

moduleFooclassBarVAL =10endclassBaz<Bar;endendObject.const_get'Foo::Baz::VAL'# => 10Object.const_get'Foo::Baz::VAL',false# => NameError

If the argument is not a valid constant name aNameError will be raised with a warning “wrong constant name”.

Object.const_get'foobar'#=> NameError: wrong constant name foobar
Source
VALUErb_mod_const_missing(VALUE klass, VALUE name){    rb_execution_context_t *ec = GET_EC();    VALUE ref = ec->private_const_reference;    rb_vm_pop_cfunc_frame();    if (ref) {        ec->private_const_reference = 0;        rb_name_err_raise("private constant %2$s::%1$s referenced", ref, name);    }    uninitialized_constant(klass, name);    UNREACHABLE_RETURN(Qnil);}

Invoked when a reference is made to an undefined constant inmod. It is passed a symbol for the undefined constant, and returns a value to be used for that constant. For example, consider:

defFoo.const_missing(name)name# return the constant name as SymbolendFoo::UNDEFINED_CONST#=> :UNDEFINED_CONST: symbol returned

As the example above shows,const_missing is not required to create the missing constant inmod, though that is often a side-effect. The caller gets its return value when triggered. If the constant is also defined, further lookups won’t hitconst_missing and will return the value stored in the constant as usual. Otherwise,const_missing will be invoked again.

In the next example, when a reference is made to an undefined constant,const_missing attempts to load a file whose path is the lowercase version of the constant name (thus classFred is assumed to be in filefred.rb). If defined as a side-effect of loading the file, the method returns the value stored in the constant. This implements an autoload feature similar toKernel#autoload andModule#autoload, though it differs in important ways.

defObject.const_missing(name)@looked_for||= {}str_name =name.to_sraise"Constant not found: #{name}"if@looked_for[str_name]@looked_for[str_name] =1file =str_name.downcaserequirefileconst_get(name,false)end
Source
static VALUErb_mod_const_set(VALUE mod, VALUE name, VALUE value){    ID id = id_for_var(mod, name, const);    if (!id) id = rb_intern_str(name);    rb_const_set(mod, id, value);    return value;}

Sets the named constant to the given object, returning that object. Creates a new constant if no constant with the given name previously existed.

Math.const_set("HIGH_SCHOOL_PI",22.0/7.0)#=> 3.14285714285714Math::HIGH_SCHOOL_PI-Math::PI#=> 0.00126448926734968

Ifsym orstr is not a valid constant name aNameError will be raised with a warning “wrong constant name”.

Object.const_set('foobar',42)#=> NameError: wrong constant name foobar
Source
static VALUErb_mod_const_source_location(int argc, VALUE *argv, VALUE mod){    VALUE name, recur, loc = Qnil;    rb_encoding *enc;    const char *pbeg, *p, *path, *pend;    ID id;    rb_check_arity(argc, 1, 2);    name = argv[0];    recur = (argc == 1) ? Qtrue : argv[1];    if (SYMBOL_P(name)) {        if (!rb_is_const_sym(name)) goto wrong_name;        id = rb_check_id(&name);        if (!id) return Qnil;        return RTEST(recur) ? rb_const_source_location(mod, id) : rb_const_source_location_at(mod, id);    }    path = StringValuePtr(name);    enc = rb_enc_get(name);    if (!rb_enc_asciicompat(enc)) {        rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");    }    pbeg = p = path;    pend = path + RSTRING_LEN(name);    if (p >= pend || !*p) {        goto wrong_name;    }    if (p + 2 < pend && p[0] == ':' && p[1] == ':') {        mod = rb_cObject;        p += 2;        pbeg = p;    }    while (p < pend) {        VALUE part;        long len, beglen;        while (p < pend && *p != ':') p++;        if (pbeg == p) goto wrong_name;        id = rb_check_id_cstr(pbeg, len = p-pbeg, enc);        beglen = pbeg-path;        if (p < pend && p[0] == ':') {            if (p + 2 >= pend || p[1] != ':') goto wrong_name;            p += 2;            pbeg = p;        }        if (!id) {            part = rb_str_subseq(name, beglen, len);            OBJ_FREEZE(part);            if (!rb_is_const_name(part)) {                name = part;                goto wrong_name;            }            else {                return Qnil;            }        }        if (!rb_is_const_id(id)) {            name = ID2SYM(id);            goto wrong_name;        }        if (p < pend) {            if (RTEST(recur)) {                mod = rb_const_get(mod, id);            }            else {                mod = rb_const_get_at(mod, id);            }            if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {                rb_raise(rb_eTypeError, "%"PRIsVALUE" does not refer to class/module",                         QUOTE(name));            }        }        else {            if (RTEST(recur)) {                loc = rb_const_source_location(mod, id);            }            else {                loc = rb_const_source_location_at(mod, id);            }            break;        }        recur = Qfalse;    }    return loc;  wrong_name:    rb_name_err_raise(wrong_constant_name, mod, name);    UNREACHABLE_RETURN(Qundef);}

Returns the Ruby source filename and line number containing the definition of the constant specified. If the named constant is not found,nil is returned. If the constant is found, but its source location can not be extracted (constant is defined in C code), empty array is returned.

inherit specifies whether to lookup inmod.ancestors (true by default).

# test.rb:classA# line 1C1 =1C2 =2endmoduleM# line 6C3 =3endclassB<A# line 10includeMC4 =4endclassA# continuation of A definitionC2 =8# constant redefinition; warned yet allowedendpB.const_source_location('C4')# => ["test.rb", 12]pB.const_source_location('C3')# => ["test.rb", 7]pB.const_source_location('C1')# => ["test.rb", 2]pB.const_source_location('C3',false)# => nil  -- don't lookup in ancestorspA.const_source_location('C2')# => ["test.rb", 16] -- actual (last) definition placepObject.const_source_location('B')# => ["test.rb", 10] -- top-level constant could be looked through ObjectpObject.const_source_location('A')# => ["test.rb", 1] -- class reopening is NOT considered new definitionpB.const_source_location('A')# => ["test.rb", 1]  -- because Object is in ancestorspM.const_source_location('A')# => ["test.rb", 1]  -- Object is not ancestor, but additionally checked for modulespObject.const_source_location('A::C1')# => ["test.rb", 2]  -- nesting is supportedpObject.const_source_location('String')# => []  -- constant is defined in C code
Source
VALUErb_mod_constants(int argc, const VALUE *argv, VALUE mod){    bool inherit = true;    if (rb_check_arity(argc, 0, 1)) inherit = RTEST(argv[0]);    if (inherit) {        return rb_const_list(rb_mod_const_of(mod, 0));    }    else {        return rb_local_constants(mod);    }}

Returns an array of the names of the constants accessible inmod. This includes the names of constants in any included modules (example at start of section), unless theinherit parameter is set tofalse.

The implementation makes no guarantees about the order in which the constants are yielded.

IO.constants.include?(:SYNC)#=> trueIO.constants(false).include?(:SYNC)#=> false

Also seeModule#const_defined?.

Source
static VALUErb_mod_define_method(int argc, VALUE *argv, VALUE mod){    const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod);    const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE};    const rb_scope_visibility_t *scope_visi = &default_scope_visi;    if (cref) {        scope_visi = CREF_SCOPE_VISI(cref);    }    return rb_mod_define_method_with_visibility(argc, argv, mod, scope_visi);}

Defines an instance method in the receiver. Themethod parameter can be aProc, aMethod or anUnboundMethod object. If a block is specified, it is used as the method body. If a block or themethod parameter has parameters, they’re used as method parameters. This block is evaluated usinginstance_eval.

classAdeffredputs"In Fred"enddefcreate_method(name,&block)self.class.define_method(name,&block)enddefine_method(:wilma) {puts"Charge it!" }define_method(:flint) {|name|puts"I'm #{name}!"}endclassB<Adefine_method(:barney,instance_method(:fred))enda =B.newa.barneya.wilmaa.flint('Dino')a.create_method(:betty) {pself }a.betty

produces:

In FredCharge it!I'm Dino!#<B:0x401b39e8>
Source
VALUErb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj){    set_const_visibility(obj, argc, argv, CONST_DEPRECATED, CONST_DEPRECATED);    return obj;}

Makes a list of existing constants deprecated. Attempt to refer to them will produce a warning.

moduleHTTPNotFound =Exception.newNOT_FOUND =NotFound# previous version of the library used this namedeprecate_constant:NOT_FOUNDendHTTP::NOT_FOUND# warning: constant HTTP::NOT_FOUND is deprecated
Source
static VALUErb_mod_freeze(VALUE mod){    rb_class_name(mod);    return rb_obj_freeze(mod);}

Prevents further modifications tomod.

This method returns self.

Source
static VALUErb_mod_include(int argc, VALUE *argv, VALUE module){    int i;    ID id_append_features, id_included;    CONST_ID(id_append_features, "append_features");    CONST_ID(id_included, "included");    if (BUILTIN_TYPE(module) == T_MODULE && FL_TEST(module, RMODULE_IS_REFINEMENT)) {        rb_raise(rb_eTypeError, "Refinement#include has been removed");    }    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);    for (i = 0; i < argc; i++) {        Check_Type(argv[i], T_MODULE);        if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {            rb_raise(rb_eTypeError, "Cannot include refinement");        }    }    while (argc--) {        rb_funcall(argv[argc], id_append_features, 1, module);        rb_funcall(argv[argc], id_included, 1, module);    }    return module;}

InvokesModule.append_features on each parameter in reverse order.

Source
VALUErb_mod_include_p(VALUE mod, VALUE mod2){    VALUE p;    Check_Type(mod2, T_MODULE);    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {        if (BUILTIN_TYPE(p) == T_ICLASS && !RICLASS_IS_ORIGIN_P(p)) {            if (METACLASS_OF(p) == mod2) return Qtrue;        }    }    return Qfalse;}

Returnstrue ifmodule is included or prepended inmod or one ofmod’s ancestors.

moduleAendclassBincludeAendclassC<BendB.include?(A)#=> trueC.include?(A)#=> trueA.include?(A)#=> false
Source
VALUErb_mod_included_modules(VALUE mod){    VALUE ary = rb_ary_new();    VALUE p;    VALUE origin = RCLASS_ORIGIN(mod);    for (p = RCLASS_SUPER(mod); p; p = RCLASS_SUPER(p)) {        if (p != origin && RCLASS_ORIGIN(p) == p && BUILTIN_TYPE(p) == T_ICLASS) {            VALUE m = METACLASS_OF(p);            if (RB_TYPE_P(m, T_MODULE))                rb_ary_push(ary, m);        }    }    return ary;}

Returns the list of modules included or prepended inmod or one ofmod’s ancestors.

moduleSubendmoduleMixinprependSubendmoduleOuterincludeMixinendMixin.included_modules#=> [Sub]Outer.included_modules#=> [Sub, Mixin]
Alias for:to_s
Source
static VALUErb_mod_instance_method(VALUE mod, VALUE vid){    ID id = rb_check_id(&vid);    if (!id) {        rb_method_name_error(mod, vid);    }    return mnew_unbound(mod, id, rb_cUnboundMethod, FALSE);}

Returns anUnboundMethod representing the given instance method inmod.

classInterpreterdefdo_a()print"there, ";enddefdo_d()print"Hello ";enddefdo_e()print"!\n";enddefdo_v()print"Dave";endDispatcher = {"a"=>instance_method(:do_a),"d"=>instance_method(:do_d),"e"=>instance_method(:do_e),"v"=>instance_method(:do_v)  }definterpret(string)string.each_char {|b|Dispatcher[b].bind(self).call }endendinterpreter =Interpreter.newinterpreter.interpret('dave')

produces:

Hellothere,Dave!
Source
VALUErb_class_instance_methods(int argc, const VALUE *argv, VALUE mod){    return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);}

Returns an array containing the names of the public and protected instance methods in the receiver. For a module, these are the public and protected methods; for a class, they are the instance (not singleton) methods. If the optional parameter isfalse, the methods of any ancestors are not included.

moduleAdefmethod1()endendclassBincludeAdefmethod2()endendclassC<Bdefmethod3()endendA.instance_methods(false)#=> [:method1]B.instance_methods(false)#=> [:method2]B.instance_methods(true).include?(:method1)#=> trueC.instance_methods(false)#=> [:method3]C.instance_methods.include?(:method2)#=> true

Note that method visibility changes in the current class, as well as aliases, are considered as methods of the current class by this method:

classC<Baliasmethod4method2protected:method2endC.instance_methods(false).sort#=> [:method2, :method3, :method4]
Source
static VALUErb_mod_method_defined(int argc, VALUE *argv, VALUE mod){    rb_method_visibility_t visi = check_definition_visibility(mod, argc, argv);    return RBOOL(visi == METHOD_VISI_PUBLIC || visi == METHOD_VISI_PROTECTED);}

Returnstrue if the named method is defined bymod. Ifinherit is set, the lookup will also searchmod’s ancestors. Public and protected methods are matched.String arguments are converted to symbols.

moduleAdefmethod1()enddefprotected_method1()endprotected:protected_method1endclassBdefmethod2()enddefprivate_method2()endprivate:private_method2endclassC<BincludeAdefmethod3()endendA.method_defined?:method1#=> trueC.method_defined?"method1"#=> trueC.method_defined?"method2"#=> trueC.method_defined?"method2",true#=> trueC.method_defined?"method2",false#=> falseC.method_defined?"method3"#=> trueC.method_defined?"protected_method1"#=> trueC.method_defined?"method4"#=> falseC.method_defined?"private_method2"#=> false
Source
static VALUErb_mod_module_eval_internal(int argc, const VALUE *argv, VALUE mod){    return specific_eval(argc, argv, mod, FALSE, RB_PASS_CALLED_KEYWORDS);}

Evaluates the string or block in the context ofmod, except that when a block is given, constant/class variable lookup is not affected. This can be used to add methods to a class.module_eval returns the result of evaluating its argument. The optionalfilename andlineno parameters set the text for error messages.

classThingenda =%q{def hello() "Hello there!" end}Thing.module_eval(a)putsThing.new.hello()Thing.module_eval("invalid code","dummy",123)

produces:

Hello there!dummy:123:in `module_eval': undefined local variable    or method `code' for Thing:Class
Also aliased as:class_eval
Source
static VALUErb_mod_module_exec_internal(int argc, const VALUE *argv, VALUE mod){    return yield_under(mod, FALSE, argc, argv, RB_PASS_CALLED_KEYWORDS);}

Evaluates the given block in the context of the class/module. The method defined in the block will belong to the receiver. Any arguments passed to the method will be passed to the block. This can be used if the block needs to access instance variables.

classThingendThing.class_exec{defhello()"Hello there!"end}putsThing.new.hello()

produces:

Hellothere!
Also aliased as:class_exec
Source
VALUErb_mod_name(VALUE mod){    // YJIT needs this function to not allocate.    bool permanent;    return classname(mod, &permanent);}

Returns the name of the modulemod. Returnsnil for anonymous modules.

Source
static VALUErb_mod_prepend(int argc, VALUE *argv, VALUE module){    int i;    ID id_prepend_features, id_prepended;    if (BUILTIN_TYPE(module) == T_MODULE && FL_TEST(module, RMODULE_IS_REFINEMENT)) {        rb_raise(rb_eTypeError, "Refinement#prepend has been removed");    }    CONST_ID(id_prepend_features, "prepend_features");    CONST_ID(id_prepended, "prepended");    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);    for (i = 0; i < argc; i++) {        Check_Type(argv[i], T_MODULE);        if (FL_TEST(argv[i], RMODULE_IS_REFINEMENT)) {            rb_raise(rb_eTypeError, "Cannot prepend refinement");        }    }    while (argc--) {        rb_funcall(argv[argc], id_prepend_features, 1, module);        rb_funcall(argv[argc], id_prepended, 1, module);    }    return module;}

InvokesModule.prepend_features on each parameter in reverse order.

Source
static VALUErb_mod_private_method(int argc, VALUE *argv, VALUE obj){    set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PRIVATE);    return obj;}

Makes existing class methods private. Often used to hide the default constructornew.

String arguments are converted to symbols. AnArray of Symbols and/or Strings is also accepted.

classSimpleSingleton# Not thread safeprivate_class_method:newdefSimpleSingleton.create(*args,&block)@me =new(*args,&block)if!@me@meendend
Source
VALUErb_mod_private_constant(int argc, const VALUE *argv, VALUE obj){    set_const_visibility(obj, argc, argv, CONST_PRIVATE, CONST_VISIBILITY_MASK);    return obj;}

Makes a list of existing constants private.

Source
VALUErb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod){    return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);}

Returns a list of the private instance methods defined inmod. If the optional parameter isfalse, the methods of any ancestors are not included.

moduleModdefmethod1()endprivate:method1defmethod2()endendMod.instance_methods#=> [:method2]Mod.private_instance_methods#=> [:method1]
Source
static VALUErb_mod_private_method_defined(int argc, VALUE *argv, VALUE mod){    return check_definition(mod, argc, argv, METHOD_VISI_PRIVATE);}

Returnstrue if the named private method is defined bymod. Ifinherit is set, the lookup will also searchmod’s ancestors.String arguments are converted to symbols.

moduleAdefmethod1()endendclassBprivatedefmethod2()endendclassC<BincludeAdefmethod3()endendA.method_defined?:method1#=> trueC.private_method_defined?"method1"#=> falseC.private_method_defined?"method2"#=> trueC.private_method_defined?"method2",true#=> trueC.private_method_defined?"method2",false#=> falseC.method_defined?"method2"#=> false
Source
VALUErb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod){    return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);}

Returns a list of the protected instance methods defined inmod. If the optional parameter isfalse, the methods of any ancestors are not included.

Source
static VALUErb_mod_protected_method_defined(int argc, VALUE *argv, VALUE mod){    return check_definition(mod, argc, argv, METHOD_VISI_PROTECTED);}

Returnstrue if the named protected method is definedmod. Ifinherit is set, the lookup will also searchmod’s ancestors.String arguments are converted to symbols.

moduleAdefmethod1()endendclassBprotecteddefmethod2()endendclassC<BincludeAdefmethod3()endendA.method_defined?:method1#=> trueC.protected_method_defined?"method1"#=> falseC.protected_method_defined?"method2"#=> trueC.protected_method_defined?"method2",true#=> trueC.protected_method_defined?"method2",false#=> falseC.method_defined?"method2"#=> true
Source
static VALUErb_mod_public_method(int argc, VALUE *argv, VALUE obj){    set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PUBLIC);    return obj;}

Makes a list of existing class methods public.

String arguments are converted to symbols. AnArray of Symbols and/or Strings is also accepted.

Source
VALUErb_mod_public_constant(int argc, const VALUE *argv, VALUE obj){    set_const_visibility(obj, argc, argv, CONST_PUBLIC, CONST_VISIBILITY_MASK);    return obj;}

Makes a list of existing constants public.

Source
static VALUErb_mod_public_instance_method(VALUE mod, VALUE vid){    ID id = rb_check_id(&vid);    if (!id) {        rb_method_name_error(mod, vid);    }    return mnew_unbound(mod, id, rb_cUnboundMethod, TRUE);}

Similar toinstance_method, searches public method only.

Source
VALUErb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod){    return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);}

Returns a list of the public instance methods defined inmod. If the optional parameter isfalse, the methods of any ancestors are not included.

Source
static VALUErb_mod_public_method_defined(int argc, VALUE *argv, VALUE mod){    return check_definition(mod, argc, argv, METHOD_VISI_PUBLIC);}

Returnstrue if the named public method is defined bymod. Ifinherit is set, the lookup will also searchmod’s ancestors.String arguments are converted to symbols.

moduleAdefmethod1()endendclassBprotecteddefmethod2()endendclassC<BincludeAdefmethod3()endendA.method_defined?:method1#=> trueC.public_method_defined?"method1"#=> trueC.public_method_defined?"method1",true#=> trueC.public_method_defined?"method1",false#=> trueC.public_method_defined?"method2"#=> falseC.method_defined?"method2"#=> true
Source
static VALUEmod_refinements(VALUE self){    ID id_refinements;    VALUE refinements;    CONST_ID(id_refinements, "__refinements__");    refinements = rb_attr_get(self, id_refinements);    if (NIL_P(refinements)) {        return rb_ary_new();    }    return rb_hash_values(refinements);}

Returns an array ofRefinement defined within the receiver.

moduleArefineIntegerdoendrefineStringdoendendpA.refinements

produces:

[#<refinement:Integer@A>, #<refinement:String@A>]
Source
VALUErb_mod_remove_cvar(VALUE mod, VALUE name){    const ID id = id_for_var_message(mod, name, class, "wrong class variable name %1$s");    st_data_t val;    if (!id) {        goto not_defined;    }    rb_check_frozen(mod);    val = rb_ivar_delete(mod, id, Qundef);    if (!UNDEF_P(val)) {        return (VALUE)val;    }    if (rb_cvar_defined(mod, id)) {        rb_name_err_raise("cannot remove %1$s for %2$s", mod, ID2SYM(id));    }  not_defined:    rb_name_err_raise("class variable %1$s not defined for %2$s",                      mod, name);    UNREACHABLE_RETURN(Qundef);}

Removes the named class variable from the receiver, returning that variable’s value.

classExample@@var =99putsremove_class_variable(:@@var)p(defined?@@var)end

produces:

99nil
Source
static VALUErb_mod_remove_method(int argc, VALUE *argv, VALUE mod){    int i;    for (i = 0; i < argc; i++) {        VALUE v = argv[i];        ID id = rb_check_id(&v);        if (!id) {            rb_name_err_raise("method '%1$s' not defined in %2$s",                              mod, v);        }        remove_method(mod, id);    }    return mod;}

Removes the method identified bysymbol from the current class. For an example, seeModule#undef_method.String arguments are converted to symbols.

Source
VALUErb_mod_set_temporary_name(VALUE mod, VALUE name){    // We don't allow setting the name if the classpath is already permanent:    if (RCLASS_PERMANENT_CLASSPATH_P(mod)) {        rb_raise(rb_eRuntimeError, "can't change permanent name");    }    if (NIL_P(name)) {        // Set the temporary classpath to NULL (anonymous):        RB_VM_LOCKING() {            set_sub_temporary_name(mod, 0);        }    }    else {        // Ensure the name is a string:        StringValue(name);        if (RSTRING_LEN(name) == 0) {            rb_raise(rb_eArgError, "empty class/module name");        }        if (is_constant_path(name)) {            rb_raise(rb_eArgError, "the temporary name must not be a constant path to avoid confusion");        }        name = rb_str_new_frozen(name);        RB_OBJ_SET_SHAREABLE(name);        // Set the temporary classpath to the given name:        RB_VM_LOCKING() {            set_sub_temporary_name(mod, name);        }    }    return mod;}

Sets the temporary name of the module. This name is reflected in introspection of the module and the values that are related to it, such as instances, constants, and methods.

The name should benil or a non-empty string that is not a valid constant path (to avoid confusing between permanent and temporary names).

The method can be useful to distinguish dynamically generated classes and modules without assigning them to constants.

If the module is given a permanent name by assigning it to a constant, the temporary name is discarded. A temporary name can’t be assigned to modules that have a permanent name.

If the given name isnil, the module becomes anonymous again.

Example:

m =Module.new# => #<Module:0x0000000102c68f38>m.name#=> nilm.set_temporary_name("fake_name")# => fake_namem.name#=> "fake_name"m.set_temporary_name(nil)# => #<Module:0x0000000102c68f38>m.name#=> nilc =Class.newc.set_temporary_name("MyClass(with description)")c.new# => #<MyClass(with description):0x0....>c::M =mc::M.name#=> "MyClass(with description)::M"# Assigning to a constant replaces the name with a permanent oneC =cC.name#=> "C"C::M.name#=> "C::M"c.new# => #<C:0x0....>
Source
static VALUErb_mod_singleton_p(VALUE klass){    return RBOOL(RCLASS_SINGLETON_P(klass));}

Returnstrue ifmod is a singleton class orfalse if it is an ordinary class or module.

classCendC.singleton_class?#=> falseC.singleton_class.singleton_class?#=> true
Source
VALUErb_mod_to_s(VALUE klass){    ID id_defined_at;    VALUE refined_class, defined_at;    if (RCLASS_SINGLETON_P(klass)) {        VALUE s = rb_usascii_str_new2("#<Class:");        VALUE v = RCLASS_ATTACHED_OBJECT(klass);        if (CLASS_OR_MODULE_P(v)) {            rb_str_append(s, rb_inspect(v));        }        else {            rb_str_append(s, rb_any_to_s(v));        }        rb_str_cat2(s, ">");        return s;    }    refined_class = rb_refinement_module_get_refined_class(klass);    if (!NIL_P(refined_class)) {        VALUE s = rb_usascii_str_new2("#<refinement:");        rb_str_concat(s, rb_inspect(refined_class));        rb_str_cat2(s, "@");        CONST_ID(id_defined_at, "__defined_at__");        defined_at = rb_attr_get(klass, id_defined_at);        rb_str_concat(s, rb_inspect(defined_at));        rb_str_cat2(s, ">");        return s;    }    return rb_class_name(klass);}

Returns a string representing this module or class. For basic classes and modules, this is the name. For singletons, we show information on the thing we’re attached to as well.

Also aliased as:inspect
Source
static VALUErb_mod_undef_method(int argc, VALUE *argv, VALUE mod){    int i;    for (i = 0; i < argc; i++) {        VALUE v = argv[i];        ID id = rb_check_id(&v);        if (!id) {            rb_method_name_error(mod, v);        }        rb_undef(mod, id);    }    return mod;}

Prevents the current class from responding to calls to the named method. Contrast this withremove_method, which deletes the method from the particular class; Ruby will still search superclasses and mixed-in modules for a possible receiver.String arguments are converted to symbols.

classParentdefhelloputs"In parent"endendclassChild<Parentdefhelloputs"In child"endendc =Child.newc.helloclassChildremove_method:hello# remove from child, still in parentendc.helloclassChildundef_method:hello# prevent any calls to 'hello'endc.hello

produces:

In childIn parentprog.rb:23: undefined method 'hello' for #<Child:0x401b3bb4> (NoMethodError)
Source
VALUErb_class_undefined_instance_methods(VALUE mod){    VALUE include_super = Qfalse;    return class_instance_method_list(1, &include_super, mod, 0, ins_methods_undef_i);}

Returns a list of the undefined instance methods defined inmod. The undefined methods of any ancestors are not included.

Private Instance Methods

Source
static VALUErb_mod_append_features(VALUE module, VALUE include){    if (!CLASS_OR_MODULE_P(include)) {        Check_Type(include, T_CLASS);    }    rb_include_module(include, module);    return module;}

When this module is included in another, Ruby callsappend_features in this module, passing it the receiving module inmod. Ruby’s default implementation is to add the constants, methods, and module variables of this module tomod if this module has not already been added tomod or one of its ancestors. See alsoModule#include.

Source
#define rb_obj_mod_const_added rb_obj_dummy1

Invoked as a callback whenever a constant is assigned on the receiver

moduleChattydefself.const_added(const_name)superputs"Added #{const_name.inspect}"endFOO =1end

produces:

Added:FOO

If we define a class using theclass keyword,const_added runs beforeinherited:

moduleMdefself.const_added(const_name)superp:const_addedendparent =Class.newdodefself.inherited(subclass)superp:inheritedendendclassChild<parentendend

produces:

:const_added:inherited
Source
static VALUErb_mod_extend_object(VALUE mod, VALUE obj){    rb_extend_object(obj, mod);    return obj;}

Extends the specified object by adding this module’s constants and methods (which are added as singleton methods). This is the callback method used byObject#extend.

modulePickydefPicky.extend_object(o)ifString===oputs"Can't add Picky to a String"elseputs"Picky added to #{o.class}"superendendend(s =Array.new).extendPicky# Call Object.extend(s ="quick brown fox").extendPicky

produces:

Picky added to ArrayCan't add Picky to a String
Source
#define rb_obj_mod_extended rb_obj_dummy1

The equivalent ofincluded, but for extended modules.

moduleAdefself.extended(mod)puts"#{self} extended in #{mod}"endendmoduleEnumerableextendAend# => prints "A extended in Enumerable"
Source
#define rb_obj_mod_included rb_obj_dummy1

Callback invoked whenever the receiver is included in another module or class. This should be used in preference toModule.append_features if your code wants to perform some action when a module is included in another.

moduleAdefA.included(mod)puts"#{self} included in #{mod}"endendmoduleEnumerableincludeAend# => prints "A included in Enumerable"
Source
#define rb_obj_mod_method_added rb_obj_dummy1

Invoked as a callback whenever an instance method is added to the receiver.

moduleChattydefself.method_added(method_name)puts"Adding #{method_name.inspect}"enddefself.some_class_method()enddefsome_instance_method()endend

produces:

Adding:some_instance_method
Source
#define rb_obj_mod_method_removed rb_obj_dummy1

Invoked as a callback whenever an instance method is removed from the receiver.

moduleChattydefself.method_removed(method_name)puts"Removing #{method_name.inspect}"enddefself.some_class_method()enddefsome_instance_method()endclass<<selfremove_method:some_class_methodendremove_method:some_instance_methodend

produces:

Removing:some_instance_method
Source
#define rb_obj_mod_method_undefined rb_obj_dummy1

Invoked as a callback whenever an instance method is undefined from the receiver.

moduleChattydefself.method_undefined(method_name)puts"Undefining #{method_name.inspect}"enddefself.some_class_method()enddefsome_instance_method()endclass<<selfundef_method:some_class_methodendundef_method:some_instance_methodend

produces:

Undefining:some_instance_method
Source
static VALUErb_mod_modfunc(int argc, VALUE *argv, VALUE module){    int i;    ID id;    const rb_method_entry_t *me;    if (!RB_TYPE_P(module, T_MODULE)) {        rb_raise(rb_eTypeError, "module_function must be called for modules");    }    if (argc == 0) {        rb_scope_module_func_set();        return Qnil;    }    set_method_visibility(module, argc, argv, METHOD_VISI_PRIVATE);    for (i = 0; i < argc; i++) {        VALUE m = module;        id = rb_to_id(argv[i]);        for (;;) {            me = search_method(m, id, 0);            if (me == 0) {                me = search_method(rb_cObject, id, 0);            }            if (UNDEFINED_METHOD_ENTRY_P(me)) {                rb_print_undef(module, id, METHOD_VISI_UNDEF);            }            if (me->def->type != VM_METHOD_TYPE_ZSUPER) {                break; /* normal case: need not to follow 'super' link */            }            m = RCLASS_SUPER(m);            if (!m)                break;        }        rb_method_entry_set(rb_singleton_class(module), id, me, METHOD_VISI_PUBLIC);    }    if (argc == 1) {        return argv[0];    }    return rb_ary_new_from_values(argc, argv);}

Creates module functions for the named methods. These functions may be called with the module as a receiver, and also become available as instance methods to classes that mix in the module. Module functions are copies of the original, and so may be changed independently. The instance-method versions are made private. If used with no arguments, subsequently defined methods become module functions.String arguments are converted to symbols. If a single argument is passed, it is returned. If no argument is passed, nil is returned. If multiple arguments are passed, the arguments are returned as an array.

moduleModdefone"This is one"endmodule_function:oneendclassClsincludeModdefcall_oneoneendendMod.one#=> "This is one"c =Cls.newc.call_one#=> "This is one"moduleModdefone"This is the new one"endendMod.one#=> "This is one"c.call_one#=> "This is the new one"
Source
static VALUErb_mod_prepend_features(VALUE module, VALUE prepend){    if (!CLASS_OR_MODULE_P(prepend)) {        Check_Type(prepend, T_CLASS);    }    rb_prepend_module(prepend, module);    return module;}

When this module is prepended in another, Ruby callsprepend_features in this module, passing it the receiving module inmod. Ruby’s default implementation is to overlay the constants, methods, and module variables of this module tomod if this module has not already been added tomod or one of its ancestors. See alsoModule#prepend.

Source
#define rb_obj_mod_prepended rb_obj_dummy1

The equivalent ofincluded, but for prepended modules.

moduleAdefself.prepended(mod)puts"#{self} prepended to #{mod}"endendmoduleEnumerableprependAend# => prints "A prepended to Enumerable"
Source
static VALUErb_mod_private(int argc, VALUE *argv, VALUE module){    return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE);}

With no arguments, sets the default visibility for subsequently defined methods to private. With arguments, sets the named methods to have private visibility.String arguments are converted to symbols. AnArray of Symbols and/or Strings is also accepted. If a single argument is passed, it is returned. If no argument is passed, nil is returned. If multiple arguments are passed, the arguments are returned as an array.

moduleModdefa()enddefb()endprivatedefc()endprivate:aendMod.private_instance_methods#=> [:a, :c]

Note that to show a private method on RDoc, use:doc:.

Source
static VALUErb_mod_protected(int argc, VALUE *argv, VALUE module){    return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED);}

Sets the visibility of a section or of a list of method names as protected. Accepts no arguments, a splat of method names (symbols or strings) or an array of method names. Returns the arguments that it received.

Important difference between protected in other languages

Protected methods in Ruby are different from other languages such as Java, where methods are marked as protected to give access to subclasses. In Ruby, subclassesalready have access to all methods defined in the parent class, even private ones.

Marking a method as protected allowsdifferent objects of the same class to call it.

One use case is for comparison methods, such as==, if we want to expose a method for comparison between objects of the same class without making the method public to objects of other classes.

Performance considerations

Protected methods are slower than others because they can’t use inline cache.

Example

classAccount# Mark balance as protected, so that we can compare between accounts# without making it public.attr_reader:balanceprotected:balancedefinitialize(balance)@balance =balanceenddef>(other)# The invocation to `other.balance` is allowed because `other` is a# different object of the same class (Account).balance>other.balanceendendaccount1 =Account.new(100)account2 =Account.new(50)account1>account2# => true (works)account1.balance# => NoMethodError (fails because balance is not public)

To show a private method on RDoc, use:doc: instead of this.

Source
static VALUErb_mod_public(int argc, VALUE *argv, VALUE module){    return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC);}

With no arguments, sets the default visibility for subsequently defined methods to public. With arguments, sets the named methods to have public visibility.String arguments are converted to symbols. AnArray of Symbols and/or Strings is also accepted. If a single argument is passed, it is returned. If no argument is passed, nil is returned. If multiple arguments are passed, the arguments are returned as an array.

Source
static VALUErb_mod_refine(VALUE module, VALUE klass){    /* module is the receiver of #refine, klass is a module to be refined (`mod` in the doc) */    rb_thread_t *th = GET_THREAD();    VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);    struct rb_refinements_data data;    if (block_handler == VM_BLOCK_HANDLER_NONE) {        rb_raise(rb_eArgError, "no block given");    }    if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {        rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");    }    ensure_class_or_module(klass);    rb_refinement_setup(&data, module, klass);    rb_yield_refine_block(data.refinement, data.refinements);    return data.refinement;}

Refinemod in the receiver.

Returns a module, where refined methods are defined.

Source
VALUErb_mod_remove_const(VALUE mod, VALUE name){    const ID id = id_for_var(mod, name, a, constant);    if (!id) {        undefined_constant(mod, name);    }    return rb_const_remove(mod, id);}

Removes the definition of the given constant, returning that constant’s previous value. If that constant referred to a module, this will not change that module’s name and can lead to confusion.

Source
static VALUErb_mod_ruby2_keywords(int argc, VALUE *argv, VALUE module){    int i;    VALUE origin_class = RCLASS_ORIGIN(module);    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);    rb_check_frozen(module);    for (i = 0; i < argc; i++) {        VALUE v = argv[i];        ID name = rb_check_id(&v);        rb_method_entry_t *me;        VALUE defined_class;        if (!name) {            rb_print_undef_str(module, v);        }        me = search_method(origin_class, name, &defined_class);        if (!me && RB_TYPE_P(module, T_MODULE)) {            me = search_method(rb_cObject, name, &defined_class);        }        if (UNDEFINED_METHOD_ENTRY_P(me) ||            UNDEFINED_REFINED_METHOD_P(me->def)) {            rb_print_undef(module, name, METHOD_VISI_UNDEF);        }        if (module == defined_class || origin_class == defined_class) {            switch (me->def->type) {              case VM_METHOD_TYPE_ISEQ:                if (ISEQ_BODY(me->def->body.iseq.iseqptr)->param.flags.has_rest &&                        !ISEQ_BODY(me->def->body.iseq.iseqptr)->param.flags.has_post &&                        !ISEQ_BODY(me->def->body.iseq.iseqptr)->param.flags.has_kw &&                        !ISEQ_BODY(me->def->body.iseq.iseqptr)->param.flags.has_kwrest) {                    ISEQ_BODY(me->def->body.iseq.iseqptr)->param.flags.ruby2_keywords = 1;                    rb_clear_method_cache(module, name);                }                else {                    rb_warn("Skipping set of ruby2_keywords flag for %"PRIsVALUE" (method accepts keywords or post arguments or method does not accept argument splat)", QUOTE_ID(name));                }                break;              case VM_METHOD_TYPE_BMETHOD: {                VALUE procval = me->def->body.bmethod.proc;                if (vm_block_handler_type(procval) == block_handler_type_proc) {                    procval = vm_proc_to_block_handler(VM_BH_TO_PROC(procval));                }                if (vm_block_handler_type(procval) == block_handler_type_iseq) {                    const struct rb_captured_block *captured = VM_BH_TO_ISEQ_BLOCK(procval);                    const rb_iseq_t *iseq = rb_iseq_check(captured->code.iseq);                    if (ISEQ_BODY(iseq)->param.flags.has_rest &&                            !ISEQ_BODY(iseq)->param.flags.has_post &&                            !ISEQ_BODY(iseq)->param.flags.has_kw &&                            !ISEQ_BODY(iseq)->param.flags.has_kwrest) {                        ISEQ_BODY(iseq)->param.flags.ruby2_keywords = 1;                        rb_clear_method_cache(module, name);                    }                    else {                        rb_warn("Skipping set of ruby2_keywords flag for %"PRIsVALUE" (method accepts keywords or post arguments or method does not accept argument splat)", QUOTE_ID(name));                    }                    break;                }              }              /* fallthrough */              default:                rb_warn("Skipping set of ruby2_keywords flag for %"PRIsVALUE" (method not defined in Ruby)", QUOTE_ID(name));                break;            }        }        else {            rb_warn("Skipping set of ruby2_keywords flag for %"PRIsVALUE" (can only set in method defining module)", QUOTE_ID(name));        }    }    return Qnil;}

For the given method names, marks the method as passing keywords through a normal argument splat. This should only be called on methods that accept an argument splat (*args) but not explicit keywords or a keyword splat. It marks the method such that if the method is called with keyword arguments, the final hash argument is marked with a special flag such that if it is the final element of a normal argument splat to another method call, and that method call does not include explicit keywords or a keyword splat, the final element is interpreted as keywords. In other words, keywords will be passed through the method to other methods.

This should only be used for methods that delegate keywords to another method, and only for backwards compatibility with Ruby versions before 3.0. Seewww.ruby-lang.org/en/news/2019/12/12/separation-of-positional-and-keyword-arguments-in-ruby-3-0/ for details on whyruby2_keywords exists and when and how to use it.

This method will probably be removed at some point, as it exists only for backwards compatibility. As it does not exist in Ruby versions before 2.7, check that the module responds to this method before calling it:

moduleModdeffoo(meth,*args,&block)send(:"do_#{meth}",*args,&block)endruby2_keywords(:foo)ifrespond_to?(:ruby2_keywords,true)end

However, be aware that if theruby2_keywords method is removed, the behavior of thefoo method using the above approach will change so that the method does not pass through keywords.

Source
static VALUEmod_using(VALUE self, VALUE module){    rb_control_frame_t *prev_cfp = previous_frame(GET_EC());    if (prev_frame_func()) {        rb_raise(rb_eRuntimeError,                 "Module#using is not permitted in methods");    }    if (prev_cfp && prev_cfp->self != self) {        rb_raise(rb_eRuntimeError, "Module#using is not called on self");    }    if (rb_block_given_p()) {        ignored_block(module, "Module#");    }    rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);    return self;}

Import class refinements frommodule into the current class or module definition.