Spec-Zone.ru › Ruby 2.3

класс Module

Родитель:
Объект

Модуль — это набор методов и констант. Методы модуля могут быть методами экземпляра или методами модуля. Методы экземпляра появляются как методы в классе, когда модуль включён, методы модуля — нет. Напротив, методы модуля могут вызываться без создания оборачивающего объекта, а методы экземпляра — нет. (См. Module#module_function.)

В следующих описаниях параметр символ относится к символу, который является либо строкой в кавычках, либо Symbol (например, :name).

module Mod
  include Math
  CONST = 1
  def meth
    #  ...
  end
end
Mod.class              #=> Module
Mod.constants          #=> [:CONST, :PI, :E]
Mod.instance_methods   #=> [:meth]

Публичные методы класса

constants → массив Показать исходный код
constants(унаследованные) → массив
static VALUE
rb_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);
}

В первом варианте возвращает массив имён всех констант, доступных с точки вызова. Этот список включает имена всех модулей и классов, определённых в глобальной области.

Module.constants.first(4)
   # => [:ARGF, :ARGV, :ArgumentError, :Array]

Module.constants.include?(:SEEK_SET)   # => false

class IO
  Module.constants.include?(:SEEK_SET) # => true
end

Второй вариант вызывает метод экземпляра constants.

nesting → массив Показать исходный код
static VALUE
rb_mod_nesting(void)
{
    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;
}

Возвращает список Modules вложенных в точке вызова.

module M1
  module M2
    $a = Module.nesting
  end
end
$a           #=> [M1::M2, M1]
$a[0].name   #=> "M1::M2"
new → модуль Показать исходный код
new {|модуль| блок } → модуль
static VALUE
rb_mod_initialize(VALUE module)
{
    if (rb_block_given_p()) {
        rb_mod_module_exec(1, &module, module);
    }
    return Qnil;
}

Создаёт новый анонимный модуль. Если блок предоставлен, он передаётся объекту модуля, и блок вычисляется в контексте этого модуля с использованием module_eval.

fred = Module.new do
  def meth1
    "hello"
  end
  def meth2
    "bye"
  end
end
a = "my string"
a.extend(fred)   #=> "my string"
a.meth1          #=> "hello"
a.meth2          #=> "bye"

Присвойте модуль константе (имя, начинающееся с заглавной буквы), если вы хотите рассматривать его как обычный модуль.

Публичные методы экземпляра

mod < other → true, false, or nil Show source
static VALUE
rb_mod_lt(VALUE mod, VALUE arg)
{
    if (mod == arg) return Qfalse;
    return rb_class_inherited_p(mod, arg);
}

Возвращает true, если mod является подклассом other. Возвращает nil, если между ними нет связи. (Подумайте о связи с точки зрения определения класса: «class A<B» подразумевает «A<B».)

mod <= other → true, false, or nil Show source
VALUE
rb_class_inherited_p(VALUE mod, VALUE arg)
{
    VALUE start = mod;

    if (mod == arg) return Qtrue;
    if (!CLASS_OR_MODULE_P(arg) && !RB_TYPE_P(arg, T_ICLASS)) {
        rb_raise(rb_eTypeError, "compared with non class/module");
    }
    arg = RCLASS_ORIGIN(arg);
    if (class_search_ancestor(mod, arg)) {
        return Qtrue;
    }
    /* not mod < arg; check if mod > arg */
    if (class_search_ancestor(arg, start)) {
        return Qfalse;
    }
    return Qnil;
}

Возвращает true, если mod является подклассом other или совпадает с other. Возвращает nil, если между ними нет связи. (Подумайте о связи с точки зрения определения класса: «class A<B» подразумевает «A<B».)

module <=> other_module → -1, 0, +1, or nil Show source
static VALUE
rb_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);
}

Сравнение — Возвращает -1, 0, +1 или nil в зависимости от того, включает ли module other_module, они одинаковы или module включен в other_module.

Возвращает nil, если module не имеет отношения к other_module, если other_module не является модулем или если два значения несравнимы.

obj == other → true or false Show source
equal?(other) → true or false
eql?(other) → true or false
VALUE
rb_obj_equal(VALUE obj1, VALUE obj2)
{
    if (obj1 == obj2) return Qtrue;
    return Qfalse;
}

Равенство — На уровне Object, == возвращает true только если obj и other являются одним и тем же объектом. Как правило, этот метод переопределяется в дочерних классах для предоставления значения, специфичного для класса.

В отличие от ==, метод equal? никогда не должен переопределяться подклассами, поскольку он используется для определения идентичности объекта (то есть, a.equal?(b) если и только если a является тем же объектом, что и b):

obj = "a"
other = obj.dup

obj == other      #=> true
obj.equal? other  #=> false
obj.equal? obj    #=> true

Метод eql? возвращает true, если obj и other ссылаются на один и тот же ключ хеша. Это используется Hash для проверки членов на равенство. Для объектов класса Object, eql? является синонимом ==. Подклассы обычно продолжают эту традицию, создавая псевдоним eql? для своего переопределенного метода ==, но есть исключения. Типы Numeric, например, выполняют преобразование типов между ==, но не между eql?, поэтому:

1 == 1.0     #=> true
1.eql? 1.0   #=> false
mod === obj → true or false Show source
static VALUE
rb_mod_eqq(VALUE mod, VALUE arg)
{
    return rb_obj_is_kind_of(arg, mod);
}

Равенство по типу — Возвращает true, если obj является экземпляром mod или экземпляром одного из потомков mod. Ограниченно используется для модулей, но может использоваться в операторах case для классификации объектов по классам.

mod > other → true, false, or nil Show source
static VALUE
rb_mod_gt(VALUE mod, VALUE arg)
{
    if (mod == arg) return Qfalse;
    return rb_mod_ge(mod, arg);
}

Возвращает true, если mod является предком other. Возвращает nil, если между ними нет связи. (Подумайте о связи с точки зрения определения класса: «class A<B» подразумевает «B>A».)

mod >= other → true, false, or nil Show source
static VALUE
rb_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);
}

Возвращает true, если mod является предком other или два модуля одинаковы. Возвращает nil, если между ними нет связи. (Подумайте о связи с точки зрения определения класса: «class A<B» подразумевает «B>A».)

ancestors → array Show source
VALUE
rb_mod_ancestors(VALUE mod)
{
    VALUE p, ary = rb_ary_new();

    for (p = mod; p; p = RCLASS_SUPER(p)) {
	if (BUILTIN_TYPE(p) == T_ICLASS) {
	    rb_ary_push(ary, RBASIC(p)->klass);
	}
	else if (p == RCLASS_ORIGIN(p)) {
	    rb_ary_push(ary, p);
	}
    }
    return ary;
}

Возвращает список модулей, включенных/добавляемых в mod (включая сам mod).

module Mod
  include Math
  include Comparable
  prepend Enumerable
end

Mod.ancestors        #=> [Enumerable, Mod, Comparable, Math]
Math.ancestors       #=> [Math]
Enumerable.ancestors #=> [Enumerable]
autoload(module, filename) → nil Show source
static VALUE
rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
{
    ID id = rb_to_id(sym);

    FilePathValue(file);
    rb_autoload_str(mod, id, file);
    return Qnil;
}

Регистрирует filename для загрузки (используя Kernel::require) в первый раз, когда module (который может быть String или символом) доступен в пространстве имен mod.

module A
end
A.autoload(:B, "b")
A::B.doit            # autoloads "b"
autoload?(name) → String or nil Show source
static VALUE
rb_mod_autoload_p(VALUE mod, VALUE sym)
{
    ID id = rb_check_id(&sym);
    if (!id) {
        return Qnil;
    }
    return rb_autoload_p(mod, id);
}

Возвращает filename для загрузки, если name зарегистрирован как autoload в пространстве имен mod.

module A
end
A.autoload(:B, "b")
A.autoload?(:B)            #=> "b"
class_eval(string [, filename [, lineno]]) → obj Show source
VALUE
rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
{
    return specific_eval(argc, argv, mod, mod);
}

Выполняет строку или блок в контексте mod, за исключением того, что когда задан блок, поиск констант/переменных класса не затрагивается. Это может использоваться для добавления методов в класс. module_eval возвращает результат вычисления своего аргумента. Необязательные параметры filename и lineno устанавливают текст для сообщений об ошибках.

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

результат:

Hello there!
dummy:123:in `module_eval': undefined local variable
    or method `code' for Thing:Class
class_exec(arg...) {|var...| block } → obj Show source
VALUE
rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
{
    return yield_under(mod, mod, rb_ary_new4(argc, argv));
}

Выполняет данный блок в контексте класса/модуля. Метод, определенный в блоке, будет принадлежать получателю. Любые аргументы, переданные методу, будут переданы блоку. Это может использоваться, если блоку необходимо получить доступ к переменным экземпляра.

class Thing
end
Thing.class_exec{
  def hello() "Hello there!" end
}
puts Thing.new.hello()

результат:

Hello there!
class_variable_defined?(symbol) → true or false Show source
class_variable_defined?(string) → true or false
static VALUE
rb_mod_cvar_defined(VALUE obj, VALUE iv)
{
    ID id = id_for_var(obj, iv, a, class);

    if (!id) {
        return Qfalse;
    }
    return rb_cvar_defined(obj, id);
}

Возвращает true, если заданная переменная класса определена в obj. Аргументы типа String преобразуются в символы.

class Fred
  @@foo = 99
end
Fred.class_variable_defined?(:@@foo)    #=> true
Fred.class_variable_defined?(:@@bar)    #=> false
class_variable_get(symbol) → obj Show source
class_variable_get(string) → obj
static VALUE
rb_mod_cvar_get(VALUE obj, VALUE iv)
{
    ID id = id_for_var(obj, iv, a, class);

    if (!id) {
        rb_name_err_raise("uninitialized class variable %1$s in %2$s",
                          obj, iv);
    }
    return rb_cvar_get(obj, id);
}

Возвращает значение заданной переменной класса (или вызывает исключение NameError). Часть имени переменной @@ должна быть включена для обычных переменных класса. Аргументы типа String преобразуются в символы.

class Fred
  @@foo = 99
end
Fred.class_variable_get(:@@foo)     #=> 99
class_variable_set(symbol, obj) → obj Show source
class_variable_set(string, obj) → obj
static VALUE
rb_mod_cvar_set(VALUE obj, VALUE iv, VALUE val)
{
    ID id = id_for_var(obj, iv, a, class);
    if (!id) id = rb_intern_str(iv);
    rb_cvar_set(obj, id, val);
    return val;
}

Устанавливает переменную класса, указанную symbol, в заданный объект. Если имя переменной класса передается как строка, эта строка преобразуется в символ.

class Fred
  @@foo = 99
  def foo
    @@foo
  end
end
Fred.class_variable_set(:@@foo, 101)     #=> 101
Fred.new.foo                             #=> 101
class_variables(inherit=true) → array Show source
VALUE
rb_mod_class_variables(int argc, const VALUE *argv, VALUE mod)
{
    VALUE inherit;
    st_table *tbl;

    if (argc == 0) {
	inherit = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &inherit);
    }
    if (RTEST(inherit)) {
	tbl = mod_cvar_of(mod, 0);
    }
    else {
	tbl = mod_cvar_at(mod, 0);
    }
    return cvar_list(tbl);
}

Возвращает массив имен переменных класса в mod. Это включает имена переменных класса в любых включенных модулях, если параметр inherit не установлен в false.

class One
  @@var1 = 1
end
class Two < One
  @@var2 = 2
end
One.class_variables          #=> [:@@var1]
Two.class_variables          #=> [:@@var2, :@@var1]
Two.class_variables(false)   #=> [:@@var2]
const_defined?(sym, inherit=true) → true или false Показать исходный код
const_defined?(str, inherit=true) → true или false
static VALUE
rb_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) {
      wrong_name:
        rb_name_err_raise(wrong_constant_name, mod, 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 (!ISUPPER(*pbeg) || !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 (RTEST(recur)) {
            if (!rb_const_defined(mod, id))
                return Qfalse;
            mod = rb_const_get(mod, id);
        }
        else {
            if (!rb_const_defined_at(mod, id))
                return Qfalse;
            mod = rb_const_get_at(mod, id);
        }
        recur = Qfalse;

        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;
}

Указывает, есть ли в mod или его предках константа с заданным именем:

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

Если mod является Module, дополнительно проверяются Object и его предки:

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

В каждом из проверяемых классов или модулей, если константа отсутствует, но существует автозагрузка для неё, true возвращается непосредственно без автозагрузки:

module Admin
  autoload :User, 'admin/user'
end
Admin.const_defined?(:User)   #=> true

Если константа не найдена, обратный вызов const_missing не вызывается, и метод возвращает false.

Если inherit равно false, поиск выполняется только в константах получателя:

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

В этом случае применяется та же логика автозагрузки.

Если аргумент не является допустимым именем константы, генерируется NameError с сообщением «неверное имя константы name»:

Hash.const_defined? 'foobar'   #=> NameError: wrong constant name foobar
const_get(sym, inherit=true) → obj Показать исходный код
const_get(str, inherit=true) → obj
static VALUE
rb_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) {
      wrong_name:
        rb_name_err_raise(wrong_constant_name, mod, 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 (!ISUPPER(*pbeg) || !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;
        }
        mod = RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
    }

    return mod;
}

Ищет константу с заданным именем в mod. Если inherit установлено, поиск также будет осуществляться в предках (и Object, если mod является Module).

Если определение константы найдено, возвращается её значение; в противном случае генерируется NameError.

Math.const_get(:PI)   #=> 3.14159265358979

Этот метод рекурсивно ищет имена констант, если предоставлено имя класса с именованным пространством. Например:

module Foo; class Bar; end end
Object.const_get 'Foo::Bar'

Флаг inherit учитывается при каждом поиске. Например:

module Foo
  class Bar
    VAL = 10
  end

  class Baz < Bar; end
end

Object.const_get 'Foo::Baz::VAL'         # => 10
Object.const_get 'Foo::Baz::VAL', false  # => NameError

Если аргумент не является допустимым именем константы, будет выброшено исключение NameError со сообщением «неверное имя константы».

Object.const_get 'foobar' #=> NameError: wrong constant name foobar
const_missing(sym) → obj Показать исходный код
VALUE
rb_mod_const_missing(VALUE klass, VALUE name)
{
    rb_vm_pop_cfunc_frame();
    uninitialized_constant(klass, name);

    UNREACHABLE;
}

Вызывается при попытке обратиться к неопределённой константе в mod. Ему передаётся символ неопределённой константы, и он возвращает значение, которое будет использоваться для этой константы. Следующий код демонстрирует пример:

def Foo.const_missing(name)
  name # return the constant name as Symbol
end

Foo::UNDEFINED_CONST    #=> :UNDEFINED_CONST: symbol returned

В следующем примере, при попытке обратиться к неопределённой константе, система пытается загрузить файл, имя которого соответствует нижнему регистру константы (предполагается, что класс Fred находится в файле fred.rb). Если файл найден, возвращается загруженный класс. Таким образом, реализуется механизм автозагрузки, аналогичный Kernel#autoload и #autoload.

def Object.const_missing(name)
  @looked_for ||= {}
  str_name = name.to_s
  raise "Class not found: #{name}" if @looked_for[str_name]
  @looked_for[str_name] = 1
  file = str_name.downcase
  require file
  klass = const_get(name)
  return klass if klass
  raise "Class not found: #{name}"
end
const_set(sym, obj) → obj Показать исходный код
const_set(str, obj) → obj
static VALUE
rb_mod_const_set(VALUE mod, VALUE name, VALUE value)
{
    ID id = id_for_setter(mod, name, const, wrong_constant_name);
    if (!id) id = rb_intern_str(name);
    rb_const_set(mod, id, value);
    return value;
}

Устанавливает значение константы с заданным именем на переданный объект и возвращает этот объект. Создаёт новую константу, если константа с таким именем ранее не существовала.

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

Если sym или str не является допустимым именем константы, будет выброшено исключение NameError с предупреждением «неверное имя константы».

Object.const_set('foobar', 42) #=> NameError: wrong constant name foobar
constants(inherit=true) → массив Показать исходный код
VALUE
rb_mod_constants(int argc, const VALUE *argv, VALUE mod)
{
    VALUE inherit;

    if (argc == 0) {
	inherit = Qtrue;
    }
    else {
	rb_scan_args(argc, argv, "01", &inherit);
    }

    if (RTEST(inherit)) {
	return rb_const_list(rb_mod_const_of(mod, 0));
    }
    else {
	return rb_local_constants(mod);
    }
}

Возвращает массив имён констант, доступных в mod. Это включает имена констант во всех подключенных модулях (пример в начале раздела), если параметр inherit не установлен в false.

Реализация не гарантирует порядок, в котором возвращаются константы.

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

См. также Module::const_defined?.

deprecate_constant(*args) Показать исходный код
VALUE
rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj)
{
    set_const_visibility(obj, argc, argv, CONST_DEPRECATED, CONST_DEPRECATED);
    return obj;
}
freeze → mod Показать исходный код
static VALUE
rb_mod_freeze(VALUE mod)
{
    rb_class_name(mod);
    return rb_obj_freeze(mod);
}

Запрещает дальнейшие изменения в mod.

Этот метод возвращает self.

include(module, ...) → self Показать исходный код
static VALUE
rb_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");

    for (i = 0; i < argc; i++)
        Check_Type(argv[i], T_MODULE);
    while (argc--) {
        rb_funcall(argv[argc], id_append_features, 1, module);
        rb_funcall(argv[argc], id_included, 1, module);
    }
    return module;
}

Вызывает Module.append_features для каждого параметра в обратном порядке.

include?(module) → true или false Показать исходный код
VALUE
rb_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) {
	    if (RBASIC(p)->klass == mod2) return Qtrue;
	}
    }
    return Qfalse;
}

Возвращает true, если module включён в mod или один из предков mod.

module A
end
class B
  include A
end
class C < B
end
B.include?(A)   #=> true
C.include?(A)   #=> true
A.include?(A)   #=> false
included_modules → массив Показать исходный код
VALUE
rb_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 && BUILTIN_TYPE(p) == T_ICLASS) {
	    VALUE m = RBASIC(p)->klass;
	    if (RB_TYPE_P(m, T_MODULE))
		rb_ary_push(ary, m);
	}
    }
    return ary;
}

Возвращает список модулей, включённых в mod.

module Mixin
end

module Outer
  include Mixin
end

Mixin.included_modules   #=> []
Outer.included_modules   #=> [Mixin]
inspect()
Псевдоним для: to_s
instance_method(symbol) → unbound_method Показать исходный код
static VALUE
rb_mod_instance_method(VALUE mod, VALUE vid)
{
    ID id = rb_check_id(&vid);
    if (!id) {
        rb_method_name_error(mod, vid);
    }
    return mnew(mod, Qundef, id, rb_cUnboundMethod, FALSE);
}

Возвращает UnboundMethod, представляющий заданный метод экземпляра в mod.

class Interpreter
  def do_a() print "there, "; end
  def do_d() print "Hello ";  end
  def do_e() print "!\n";     end
  def do_v() print "Dave";    end
  Dispatcher = {
    "a" => instance_method(:do_a),
    "d" => instance_method(:do_d),
    "e" => instance_method(:do_e),
    "v" => instance_method(:do_v)
  }
  def interpret(string)
    string.each_char {|b| Dispatcher[b].bind(self).call }
  end
end

interpreter = Interpreter.new
interpreter.interpret('dave')

выводит:

Hello there, Dave!
instance_methods(include_super=true) → массив Показать исходный код
VALUE
rb_class_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
    return class_instance_method_list(argc, argv, mod, 0, ins_methods_i);
}

Возвращает массив, содержащий имена публичных и защищённых методов экземпляров в получателе. Для модуля это публичные и защищённые методы; для класса - методы экземпляра (не синглетона). Если необязательный параметр равен false, методы предков не включаются.

module A
  def method1()  end
end
class B
  include A
  def method2()  end
end
class C < B
  def method3()  end
end

A.instance_methods(false)                   #=> [:method1]
B.instance_methods(false)                   #=> [:method2]
B.instance_methods(true).include?(:method1) #=> true
C.instance_methods(false)                   #=> [:method3]
C.instance_methods.include?(:method2)       #=> true
method_defined?(symbol) → true или false
method_defined?(string) → true или false
static VALUE
rb_mod_method_defined(VALUE mod, VALUE mid)
{
    ID id = rb_check_id(&mid);
    if (!id || !rb_method_boundp(mod, id, 1)) {
        return Qfalse;
    }
    return Qtrue;

}

Возвращает true, если указанный метод определён в mod (или его включённых модулях и, если mod является классом, в его предках). Сопоставляются публичные и защищённые методы. Строковые аргументы преобразуются в символы.

module A
  def method1()  end
  def protected_method1()  end
  protected :protected_method1
end
class B
  def method2()  end
  def private_method2()  end
  private :private_method2
end
class C < B
  include A
  def method3()  end
end

A.method_defined? :method1              #=> true
C.method_defined? "method1"             #=> true
C.method_defined? "method2"             #=> true
C.method_defined? "method3"             #=> true
C.method_defined? "protected_method1"   #=> true
C.method_defined? "method4"             #=> false
C.method_defined? "private_method2"     #=> false
module_eval {|| block } → obj Показать исходный код
VALUE
rb_mod_module_eval(int argc, const VALUE *argv, VALUE mod)
{
    return specific_eval(argc, argv, mod, mod);
}

Вычисляет строку или блок в контексте mod, за исключением того, что при передаче блока, поиск констант/классовых переменных не затрагивается. Это можно использовать для добавления методов к классу. module_eval возвращает результат вычисления своего аргумента. Необязательные параметры filename и lineno задают текст сообщений об ошибках.

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

выводит:

Hello there!
dummy:123:in `module_eval': undefined local variable
    or method `code' for Thing:Class
module_exec(arg...) {|var...| block } → obj Показать исходный код
VALUE
rb_mod_module_exec(int argc, const VALUE *argv, VALUE mod)
{
    return yield_under(mod, mod, rb_ary_new4(argc, argv));
}

Вычисляет переданный блок в контексте класса/модуля. Метод, определённый в блоке, будет принадлежать получателю. Любые аргументы, переданные методу, будут переданы блоку. Это можно использовать, если блоку нужно получить доступ к переменным экземпляра.

class Thing
end
Thing.class_exec{
  def hello() "Hello there!" end
}
puts Thing.new.hello()

выводит:

Hello there!
name → строка Показать исходный код
VALUE
rb_mod_name(VALUE mod)
{
    int permanent;
    VALUE path = classname(mod, &permanent);

    if (!NIL_P(path)) return rb_str_dup(path);
    return path;
}

Возвращает имя модуля mod. Возвращает nil для безымянных модулей.

prepend(module, ...) → self Показать исходный код
static VALUE
rb_mod_prepend(int argc, VALUE *argv, VALUE module)
{
    int i;
    ID id_prepend_features, id_prepended;

    CONST_ID(id_prepend_features, "prepend_features");
    CONST_ID(id_prepended, "prepended");
    for (i = 0; i < argc; i++)
        Check_Type(argv[i], T_MODULE);
    while (argc--) {
        rb_funcall(argv[argc], id_prepend_features, 1, module);
        rb_funcall(argv[argc], id_prepended, 1, module);
    }
    return module;
}

Вызывает Module.prepend_features для каждого параметра в обратном порядке.

private_class_method(symbol, ...) → mod Показать исходный код
private_class_method(string, ...) → mod
static VALUE
rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
{
    set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PRIVATE);
    return obj;
}

Делает существующие методы класса закрытыми. Часто используется для скрытия конструктора по умолчанию new.

Строковые аргументы преобразуются в символы.

class SimpleSingleton  # Not thread safe
  private_class_method :new
  def SimpleSingleton.create(*args, &block)
    @me = new(*args, &block) if ! @me
    @me
  end
end
private_constant(symbol, ...) → mod Показать исходный код
VALUE
rb_mod_private_constant(int argc, const VALUE *argv, VALUE obj)
{
    set_const_visibility(obj, argc, argv, CONST_PRIVATE, CONST_VISIBILITY_MASK);
    return obj;
}

Делает список существующих констант закрытыми.

private_instance_methods(include_super=true) → array Показать исходный код
VALUE
rb_class_private_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
    return class_instance_method_list(argc, argv, mod, 0, ins_methods_priv_i);
}

Возвращает список закрытых методов экземпляра, определенных в mod. Если необязательный параметр равен false, методы предков не включаются.

module Mod
  def method1()  end
  private :method1
  def method2()  end
end
Mod.instance_methods           #=> [:method2]
Mod.private_instance_methods   #=> [:method1]
private_method_defined?(symbol) → true or false Показать исходный код
private_method_defined?(string) → true or false
static VALUE
rb_mod_private_method_defined(VALUE mod, VALUE mid)
{
    return check_definition(mod, mid, METHOD_VISI_PRIVATE);
}

Возвращает true, если указанный закрытый метод определен в _ mod_ (или включенных модулях и, если mod - класс, его предках). Строковые аргументы преобразуются в символы.

module A
  def method1()  end
end
class B
  private
  def method2()  end
end
class C < B
  include A
  def method3()  end
end

A.method_defined? :method1            #=> true
C.private_method_defined? "method1"   #=> false
C.private_method_defined? "method2"   #=> true
C.method_defined? "method2"           #=> false
protected_instance_methods(include_super=true) → array Показать исходный код
VALUE
rb_class_protected_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
    return class_instance_method_list(argc, argv, mod, 0, ins_methods_prot_i);
}

Возвращает список защищенных методов экземпляра, определенных в mod. Если необязательный параметр равен false, методы предков не включаются.

protected_method_defined?(symbol) → true or false Показать исходный код
protected_method_defined?(string) → true or false
static VALUE
rb_mod_protected_method_defined(VALUE mod, VALUE mid)
{
    return check_definition(mod, mid, METHOD_VISI_PROTECTED);
}

Возвращает true, если указанный защищенный метод определен в mod (или включенных модулях и, если mod - класс, его предках). Строковые аргументы преобразуются в символы.

module A
  def method1()  end
end
class B
  protected
  def method2()  end
end
class C < B
  include A
  def method3()  end
end

A.method_defined? :method1              #=> true
C.protected_method_defined? "method1"   #=> false
C.protected_method_defined? "method2"   #=> true
C.method_defined? "method2"             #=> true
psych_yaml_as(url) Показать исходный код
# File ext/psych/lib/psych/core_ext.rb, line 22
def psych_yaml_as url
  return if caller[0].end_with?('rubytypes.rb')
  if $VERBOSE
    warn "#{caller[0]}: yaml_as is deprecated, please use yaml_tag"
  end
  Psych.add_tag(url, self)
end
Также алиас: yaml_as
public_class_method(symbol, ...) → mod Показать исходный код
public_class_method(string, ...) → mod
static VALUE
rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
{
    set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PUBLIC);
    return obj;
}

Делает список существующих методов класса общедоступными.

Строковые аргументы преобразуются в символы.

public_constant(symbol, ...) → mod Показать исходный код
VALUE
rb_mod_public_constant(int argc, const VALUE *argv, VALUE obj)
{
    set_const_visibility(obj, argc, argv, CONST_PUBLIC, CONST_VISIBILITY_MASK);
    return obj;
}

Делает список существующих констант общедоступными.

public_instance_method(symbol) → unbound_method Показать исходный код
static VALUE
rb_mod_public_instance_method(VALUE mod, VALUE vid)
{
    ID id = rb_check_id(&vid);
    if (!id) {
        rb_method_name_error(mod, vid);
    }
    return mnew(mod, Qundef, id, rb_cUnboundMethod, TRUE);
}

Аналогично instance_method, но ищет только общедоступные методы.

public_instance_methods(include_super=true) → array Показать исходный код
VALUE
rb_class_public_instance_methods(int argc, const VALUE *argv, VALUE mod)
{
    return class_instance_method_list(argc, argv, mod, 0, ins_methods_pub_i);
}

Возвращает список общедоступных методов экземпляра, определенных в mod. Если необязательный параметр равен false, методы предков не включаются.

public_method_defined?(symbol) → true or false Показать исходный код
public_method_defined?(string) → true or false
static VALUE
rb_mod_public_method_defined(VALUE mod, VALUE mid)
{
    return check_definition(mod, mid, METHOD_VISI_PUBLIC);
}

Возвращает true, если указанный общедоступный метод определен в mod (или включенных модулях и, если mod - класс, его предках). Строковые аргументы преобразуются в символы.

module A
  def method1()  end
end
class B
  protected
  def method2()  end
end
class C < B
  include A
  def method3()  end
end

A.method_defined? :method1           #=> true
C.public_method_defined? "method1"   #=> true
C.public_method_defined? "method2"   #=> false
C.method_defined? "method2"          #=> true
remove_class_variable(sym) → obj Показать исходный код
VALUE
rb_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, n = id;

    if (!id) {
      not_defined:
	rb_name_err_raise("class variable %1$s not defined for %2$s",
			  mod, name);
    }
    rb_check_frozen(mod);
    if (RCLASS_IV_TBL(mod) && st_delete(RCLASS_IV_TBL(mod), &n, &val)) {
	return (VALUE)val;
    }
    if (rb_cvar_defined(mod, id)) {
	rb_name_err_raise("cannot remove %1$s for %2$s", mod, ID2SYM(id));
    }
    goto not_defined;
}

Удаляет определение sym, возвращая значение этой константы.

class Dummy
  @@var = 99
  puts @@var
  remove_class_variable(:@@var)
  p(defined? @@var)
end

результат:

99
nil
singleton_class? → true or false Показать исходный код
static VALUE
rb_mod_singleton_p(VALUE klass)
{
    if (RB_TYPE_P(klass, T_CLASS) && FL_TEST(klass, FL_SINGLETON))
        return Qtrue;
    return Qfalse;
}

Возвращает true, если mod - одиночный класс, или false, если это обычный класс или модуль.

class C
end
C.singleton_class?                  #=> false
C.singleton_class.singleton_class?  #=> true
to_s → string Показать исходный код
static VALUE
rb_mod_to_s(VALUE klass)
{
    ID id_defined_at;
    VALUE refined_class, defined_at;

    if (FL_TEST(klass, FL_SINGLETON)) {
        VALUE s = rb_usascii_str_new2("#<Class:");
        VALUE v = rb_ivar_get(klass, id__attached__);

        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_str_dup(rb_class_name(klass));
}

Возвращает строку, представляющую данный модуль или класс. Для базовых классов и модулей это имя. Для одиночных объектов мы также показываем информацию об объекте, к которому мы прикреплены.

Также алиас: inspect
yaml_as(url)
Алиас для: psych_yaml_as
END_OF_DOCUMENT_MARKER

Приватные методы экземпляра

alias_method(new_name, old_name) → self Show source
static VALUE
rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
{
    ID oldid = rb_check_id(&oldname);
    if (!oldid) {
        rb_print_undef_str(mod, oldname);
    }
    rb_alias(mod, rb_to_id(newname), oldid);
    return mod;
}

Создает new_name как новую копию метода old_name. Это может быть использовано для сохранения доступа к методам, которые переопределены.

module Mod
  alias_method :orig_exit, :exit
  def exit(code=0)
    puts "Exiting with code #{code}"
    orig_exit(code)
  end
end
include Mod
exit(99)

результат:

Exiting with code 99
append_features(mod) → mod Show source
static VALUE
rb_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;
}

Когда этот модуль включается в другой, Ruby вызывает append_features в этом модуле, передавая ему принимающий модуль в mod. Реализация по умолчанию в Ruby заключается в добавлении констант, методов и переменных модуля в mod, если этот модуль еще не был добавлен в mod или один из его предков. См. также Module#include.

attr(*args) Show source
VALUE
rb_mod_attr(int argc, VALUE *argv, VALUE klass)
{
    if (argc == 2 && (argv[1] == Qtrue || argv[1] == Qfalse)) {
        rb_warning("optional boolean argument is obsoleted");
        rb_attr(klass, id_for_attr(klass, argv[0]), 1, RTEST(argv[1]), TRUE);
        return Qnil;
    }
    return rb_mod_attr_reader(argc, argv, klass);
}
attr_accessor(symbol, ...) → nil Show source
attr_accessor(string, ...) → nil
static VALUE
rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass)
{
    int i;

    for (i=0; i<argc; i++) {
        rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, TRUE, TRUE);
    }
    return Qnil;
}

Определяет именованный атрибут для этого модуля, где имя — это symbol.id2name, создавая переменную экземпляра (@name) и соответствующий метод доступа для ее чтения. Также создает метод под названием name= для установки атрибута. Строковые аргументы преобразуются в символы.

module Mod
  attr_accessor(:one, :two)
end
Mod.instance_methods.sort   #=> [:one, :one=, :two, :two=]
attr_reader(symbol, ...) → nil Show source
attr(symbol, ...) → nil
attr_reader(string, ...) → nil
attr(string, ...) → nil
static VALUE
rb_mod_attr_reader(int argc, VALUE *argv, VALUE klass)
{
    int i;

    for (i=0; i<argc; i++) {
        rb_attr(klass, id_for_attr(klass, argv[i]), TRUE, FALSE, TRUE);
    }
    return Qnil;
}

Создает переменные экземпляра и соответствующие методы, которые возвращают значение каждой переменной экземпляра. Эквивалентно вызову “attr:name'' для каждого имени по очереди. Строковые аргументы преобразуются в символы.

attr_writer(symbol, ...) → nil Show source
attr_writer(string, ...) → nil
static VALUE
rb_mod_attr_writer(int argc, VALUE *argv, VALUE klass)
{
    int i;

    for (i=0; i<argc; i++) {
        rb_attr(klass, id_for_attr(klass, argv[i]), FALSE, TRUE, TRUE);
    }
    return Qnil;
}

Создает метод доступа для присваивания атрибуту symbol.id2name. Строковые аргументы преобразуются в символы.

define_method(symbol, method) → symbol Show source
define_method(symbol) { block } → symbol
static VALUE
rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
{
    ID id;
    VALUE body;
    VALUE name;
    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;
    int is_method = FALSE;

    if (cref) {
        scope_visi = CREF_SCOPE_VISI(cref);
    }

    rb_check_arity(argc, 1, 2);
    name = argv[0];
    id = rb_check_id(&name);
    if (argc == 1) {
#if PROC_NEW_REQUIRES_BLOCK
        body = rb_block_lambda();
#else
        rb_thread_t *th = GET_THREAD();
        rb_block_t *block = rb_vm_control_frame_block_ptr(th->cfp);
        if (!block) rb_raise(rb_eArgError, proc_without_block);

        body = block->proc;

        if (SYMBOL_P(body)) {
            body = rb_sym_to_proc(body);
        }
        else if (!body) {
            body = rb_vm_make_proc_lambda(th, block, rb_cProc, TRUE);
        }
#endif
    }
    else {
        body = argv[1];

        if (rb_obj_is_method(body)) {
            is_method = TRUE;
        }
        else if (rb_obj_is_proc(body)) {
            is_method = FALSE;
        }
        else {
            rb_raise(rb_eTypeError,
                     "wrong argument type %s (expected Proc/Method)",
                     rb_obj_classname(body));
        }
    }
    if (!id) id = rb_to_id(name);

    if (is_method) {
        struct METHOD *method = (struct METHOD *)DATA_PTR(body);
        if (method->me->owner != mod && !RB_TYPE_P(method->me->owner, T_MODULE) &&
            !RTEST(rb_class_inherited_p(mod, method->me->owner))) {
            if (FL_TEST(method->me->owner, FL_SINGLETON)) {
                rb_raise(rb_eTypeError,
                         "can't bind singleton method to a different class");
            }
            else {
                rb_raise(rb_eTypeError,
                         "bind argument must be a subclass of % "PRIsVALUE,
                         rb_class_name(method->me->owner));
            }
        }
        rb_method_entry_set(mod, id, method->me, scope_visi->method_visi);
        if (scope_visi->module_func) {
            rb_method_entry_set(rb_singleton_class(mod), id, method->me, METHOD_VISI_PUBLIC);
        }
        RB_GC_GUARD(body);
    }
    else {
        rb_proc_t *proc;
        body = proc_dup(body);
        GetProcPtr(body, proc);
        if (RUBY_VM_NORMAL_ISEQ_P(proc->block.iseq)) {
            proc->is_lambda = TRUE;
            proc->is_from_method = TRUE;
        }
        rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, scope_visi->method_visi);
        if (scope_visi->module_func) {
            rb_add_method(rb_singleton_class(mod), id, VM_METHOD_TYPE_BMETHOD, (void *)body, METHOD_VISI_PUBLIC);
        }
    }

    return ID2SYM(id);
}

Определяет метод экземпляра в получателе. Параметр method может быть Proc, Method или UnboundMethod объектом. Если указан блок, он используется в качестве тела метода. Этот блок вычисляется с использованием instance_eval, точка, которую сложно продемонстрировать, потому что define_method является приватным. (Вот почему мы прибегаем к send трюку в этом примере.)

class A
  def fred
    puts "In Fred"
  end
  def create_method(name, &block)
    self.class.send(:define_method, name, &block)
  end
  define_method(:wilma) { puts "Charge it!" }
end
class B < A
  define_method(:barney, instance_method(:fred))
end
a = B.new
a.barney
a.wilma
a.create_method(:betty) { p self }
a.betty

результат:

In Fred
Charge it!
#<B:0x401b39e8>
extend_object(obj) → obj Show source
static VALUE
rb_mod_extend_object(VALUE mod, VALUE obj)
{
    rb_extend_object(obj, mod);
    return obj;
}

Расширяет указанный объект, добавляя константы и методы этого модуля (которые добавляются как одиночные методы). Это метод обратного вызова, используемый Object#extend.

module Picky
  def Picky.extend_object(o)
    if String === o
      puts "Can't add Picky to a String"
    else
      puts "Picky added to #{o.class}"
      super
    end
  end
end
(s = Array.new).extend Picky  # Call Object.extend
(s = "quick brown fox").extend Picky

результат:

Picky added to Array
Can't add Picky to a String
extended(othermod) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Эквивалент included, но для расширенных модулей.

module A
  def self.extended(mod)
    puts "#{self} extended in #{mod}"
  end
end
module Enumerable
  extend A
end
 # => prints "A extended in Enumerable"
included(othermod) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Обратный вызов, вызываемый всякий раз, когда получатель включается в другой модуль или класс. Его следует использовать вместо Module.append_features, если ваш код хочет выполнить какое-либо действие, когда модуль включен в другой.

module A
  def A.included(mod)
    puts "#{self} included in #{mod}"
  end
end
module Enumerable
  include A
end
 # => prints "A included in Enumerable"
method_added(method_name) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Вызывается как обратный вызов всякий раз, когда метод экземпляра добавляется к получателю.

module Chatty
  def self.method_added(method_name)
    puts "Adding #{method_name.inspect}"
  end
  def self.some_class_method() end
  def some_instance_method() end
end

результат:

Adding :some_instance_method
method_removed(method_name) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Вызывается как обратный вызов всякий раз, когда метод экземпляра удаляется из получателя.

module Chatty
  def self.method_removed(method_name)
    puts "Removing #{method_name.inspect}"
  end
  def self.some_class_method() end
  def some_instance_method() end
  class << self
    remove_method :some_class_method
  end
  remove_method :some_instance_method
end

результат:

Removing :some_instance_method
method_undefined(p1) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Не задокументировано

module_function(symbol, ...) → self Show source
module_function(string, ...) → self
static VALUE
rb_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 module;
    }

    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, 0);
            }
            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);
    }
    return module;
}

Создает функции модуля для указанных методов. Эти функции могут вызываться с модулем в качестве получателя, а также становятся доступными как методы экземпляра для классов, которые смешивают модуль. Функции Module являются копиями оригинала и поэтому могут изменяться независимо. Версии методов экземпляра делаются приватными. Если используется без аргументов, последующие определенные методы становятся функциями модуля. Строковые аргументы преобразуются в символы.

module Mod
  def one
    "This is one"
  end
  module_function :one
end
class Cls
  include Mod
  def call_one
    one
  end
end
Mod.one     #=> "This is one"
c = Cls.new
c.call_one  #=> "This is one"
module Mod
  def one
    "This is the new one"
  end
end
Mod.one     #=> "This is one"
c.call_one  #=> "This is the new one"
prepend_features(mod) → mod Show source
static VALUE
rb_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;
}

Когда этот модуль добавляется в начало другого, Ruby вызывает prepend_features в этом модуле, передавая ему принимающий модуль в mod. Реализация по умолчанию в Ruby заключается в наложении констант, методов и переменных модуля на mod, если этот модуль еще не был добавлен в mod или один из его предков. См. также Module#prepend.

prepended(othermod) Show source
static VALUE
rb_obj_dummy(void)
{
    return Qnil;
}

Эквивалент included, но для модулей, добавленных в начало.

module A
  def self.prepended(mod)
    puts "#{self} prepended to #{mod}"
  end
end
module Enumerable
  prepend A
end
 # => prints "A prepended to Enumerable"
private → self Show source
private(symbol, ...) → self
private(string, ...) → self
static VALUE
rb_mod_private(int argc, VALUE *argv, VALUE module)
{
    return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE);
}

Без аргументов устанавливает видимость по умолчанию для последующих определенных методов как приватную. С аргументами устанавливает указанные методы как имеющие приватную видимость. Строковые аргументы преобразуются в символы.

module Mod
  def a()  end
  def b()  end
  private
  def c()  end
  private :a
end
Mod.private_instance_methods   #=> [:a, :c]
protected → self Show source
protected(symbol, ...) → self
protected(string, ...) → self
static VALUE
rb_mod_protected(int argc, VALUE *argv, VALUE module)
{
    return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED);
}

Без аргументов устанавливает видимость по умолчанию для последующих определенных методов как защищенную. С аргументами устанавливает указанные методы как имеющие защищенную видимость. Строковые аргументы преобразуются в символы.

public → self Показать исходный код
public(symbol, ...) → self
public(string, ...) → self
static VALUE
rb_mod_public(int argc, VALUE *argv, VALUE module)
{
    return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC);
}

Без аргументов устанавливает значение по умолчанию для видимости методов, определённых в дальнейшем, в общедоступное (public). С аргументами устанавливает видимость указанных методов в общедоступном (public) режиме. Строковые аргументы преобразуются в символы.

refine(klass) { block } → module Показать исходный код
static VALUE
rb_mod_refine(VALUE module, VALUE klass)
{
    VALUE refinement;
    ID id_refinements, id_activated_refinements,
       id_refined_class, id_defined_at;
    VALUE refinements, activated_refinements;
    rb_thread_t *th = GET_THREAD();
    rb_block_t *block = rb_vm_control_frame_block_ptr(th->cfp);

    if (!block) {
        rb_raise(rb_eArgError, "no block given");
    }
    if (block->proc) {
        rb_raise(rb_eArgError,
                 "can't pass a Proc as a block to Module#refine");
    }
    Check_Type(klass, T_CLASS);
    CONST_ID(id_refinements, "__refinements__");
    refinements = rb_attr_get(module, id_refinements);
    if (NIL_P(refinements)) {
        refinements = hidden_identity_hash_new();
        rb_ivar_set(module, id_refinements, refinements);
    }
    CONST_ID(id_activated_refinements, "__activated_refinements__");
    activated_refinements = rb_attr_get(module, id_activated_refinements);
    if (NIL_P(activated_refinements)) {
        activated_refinements = hidden_identity_hash_new();
        rb_ivar_set(module, id_activated_refinements,
                    activated_refinements);
    }
    refinement = rb_hash_lookup(refinements, klass);
    if (NIL_P(refinement)) {
        refinement = rb_module_new();
        RCLASS_SET_SUPER(refinement, klass);
        FL_SET(refinement, RMODULE_IS_REFINEMENT);
        CONST_ID(id_refined_class, "__refined_class__");
        rb_ivar_set(refinement, id_refined_class, klass);
        CONST_ID(id_defined_at, "__defined_at__");
        rb_ivar_set(refinement, id_defined_at, module);
        rb_hash_aset(refinements, klass, refinement);
        add_activated_refinement(activated_refinements, klass, refinement);
    }
    rb_yield_refine_block(refinement, activated_refinements);
    return refinement;
}

Уточнить klass в получателе.

Возвращает наложенный модуль.

remove_const(sym) → obj Показать исходный код
VALUE
rb_mod_remove_const(VALUE mod, VALUE name)
{
    const ID id = id_for_var(mod, name, a, constant);

    if (!id) {
	rb_name_err_raise("constant %2$s::%1$s not defined",
			  mod, name);
    }
    return rb_const_remove(mod, id);
}

Удаляет определение заданной константы, возвращая предыдущее значение этой константы. Если эта константа ссылалась на модуль, это не изменит имя модуля и может привести к путанице.

remove_method(symbol) → self Показать исходный код
remove_method(string) → self
static VALUE
rb_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;
}

Удаляет метод, идентифицируемый символом symbol, из текущего класса. Пример см. в Module.undef_method. Строковые аргументы преобразуются в символы.

undef_method(symbol) → self Показать исходный код
undef_method(string) → self
static VALUE
rb_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;
}

Предотвращает текущий класс от реагирования на вызовы указанного метода. В отличие от remove_method, который удаляет метод из конкретного класса; Ruby всё равно будет искать в суперклассах и включённых модулях возможного получателя. Строковые аргументы преобразуются в символы.

class Parent
  def hello
    puts "In parent"
  end
end
class Child < Parent
  def hello
    puts "In child"
  end
end

c = Child.new
c.hello

class Child
  remove_method :hello  # remove from child, still in parent
end
c.hello

class Child
  undef_method :hello   # prevent any calls to 'hello'
end
c.hello

Результат:

In child
In parent
prog.rb:23: undefined method `hello' for #<Child:0x401b3bb4> (NoMethodError)
using(module) → self Показать исходный код
static VALUE
mod_using(VALUE self, VALUE module)
{
    rb_control_frame_t *prev_cfp = previous_frame(GET_THREAD());

    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");
    }
    rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
    return self;
}

Импортирует уточнения классов из модуля module в текущее определение класса или модуля.

Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API