Spec-Zone.ru › Ruby 4.0

класс Class

Родительский класс:
Модуль

Классы в Ruby — это объекты первого класса: каждый из них является экземпляром класса Class.

Обычно новый класс создают с помощью:

class Name
 # some code describing the class behavior
end

При создании нового класса инициализируется объект типа Class и присваивается глобальной константе (в данном случае Name).

Когда вызывается Name.new для создания нового объекта, по умолчанию запускается метод new класса Class. Это можно продемонстрировать, переопределив new в классе Class:

class Class
  alias old_new new
  def new(*args)
    print "Creating a new ", self.name, "\n"
    old_new(*args)
  end
end

class Name
end

n = Name.new

Результат:

Creating a new Name

Классы, модули и объекты взаимосвязаны. На следующей диаграмме вертикальные стрелки обозначают наследование, а скобки — метаклассы. Все метаклассы являются экземплярами класса «Class».

                         +---------+             +-...
                         |         |             |
         BasicObject-----|-->(BasicObject)-------|-...
             ^           |         ^             |
             |           |         |             |
          Object---------|----->(Object)---------|-...
             ^           |         ^             |
             |           |         |             |
             +-------+   |         +--------+    |
             |       |   |         |        |    |
             |    Module-|---------|--->(Module)-|-...
             |       ^   |         |        ^    |
             |       |   |         |        |    |
             |     Class-|---------|---->(Class)-|-...
             |       ^   |         |        ^    |
             |       +---+         |        +----+
             |                     |
obj--->OtherClass---------->(OtherClass)-----------...

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

new(super_class=Object) → a_class Показать исходный код
new(super_class=Object) { |mod| ... } → a_class
static VALUE
rb_class_initialize(int argc, VALUE *argv, VALUE klass)
{
    VALUE super;

    if (RCLASS_SUPER(klass) != 0 || klass == rb_cBasicObject) {
        rb_raise(rb_eTypeError, "already initialized class");
    }
    if (rb_check_arity(argc, 0, 1) == 0) {
        super = rb_cObject;
    }
    else {
        super = argv[0];
        rb_check_inheritable(super);
        if (!RCLASS_INITIALIZED_P(super)) {
            rb_raise(rb_eTypeError, "can't inherit uninitialized class");
        }
    }
    rb_class_set_super(klass, super);
    rb_make_metaclass(klass, RBASIC(super)->klass);
    rb_class_inherited(super, klass);
    rb_mod_initialize_exec(klass);

    return klass;
}

Создаёт новый анонимный (безымянный) класс с указанным суперклассом (или Object, если параметр не задан). Чтобы присвоить классу имя, можно связать объект класса с константой.

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

fred = Class.new do
  def meth1
    "hello"
  end
  def meth2
    "bye"
  end
end

a = fred.new     #=> #<#<Class:0x100381890>:0x100376b98>
a.meth1          #=> "hello"
a.meth2          #=> "bye"

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

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

allocate() → obj Показать исходный код
static VALUE
rb_class_alloc(VALUE klass)
{
    rb_alloc_func_t allocator = class_get_alloc_func(klass);
    return class_call_alloc_func(allocator, klass);
}

Выделяет память для нового объекта класса class, не вызывая initialize для нового экземпляра. Возвращённый объект должен быть экземпляром класса class.

klass = Class.new do
  def initialize(*args)
    @initialized = true
  end

  def initialized?
    @initialized || false
  end
end

klass.allocate.initialized? #=> false
attached_object → object Показать исходный код
VALUE
rb_class_attached_object(VALUE klass)
{
    if (!RCLASS_SINGLETON_P(klass)) {
        rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass);
    }

    return RCLASS_ATTACHED_OBJECT(klass);
}

Возвращает объект, для которого получатель является синглтон-классом.

Вызывает TypeError, если класс не является синглтон-классом.

class Foo; end

Foo.singleton_class.attached_object        #=> Foo
Foo.attached_object                        #=> TypeError: `Foo' is not a singleton class
Foo.new.singleton_class.attached_object    #=> #<Foo:0x000000010491a370>
TrueClass.attached_object                  #=> TypeError: `TrueClass' is not a singleton class
NilClass.attached_object                   #=> TypeError: `NilClass' is not a singleton class
new(args, ...) → obj Показать исходный код
VALUE
rb_class_new_instance_pass_kw(int argc, const VALUE *argv, VALUE klass)
{
    VALUE obj;

    obj = rb_class_alloc(klass);
    rb_obj_call_init_kw(obj, argc, argv, RB_PASS_CALLED_KEYWORDS);

    return obj;
}

Вызывает allocate, чтобы создать новый объект класса class, а затем вызывает метод initialize этого объекта, передавая ему args. Именно этот метод вызывается при создании объекта с помощью .new.

subclasses → array Показать исходный код
VALUE
rb_class_subclasses(VALUE klass)
{
    return class_descendants(klass, true);
}

Возвращает массив классов, для которых получатель является непосредственным суперклассом, исключая синглтон-классы. Порядок элементов в возвращаемом массиве не определён.

class A; end
class B < A; end
class C < B; end
class D < A; end

A.subclasses        #=> [D, B]
B.subclasses        #=> [C]
C.subclasses        #=> []

Анонимные подклассы (не связанные с константой) также возвращаются:

c = Class.new(A)
A.subclasses        # => [#<Class:0x00007f003c77bd78>, D, B]

Обратите внимание, что родительский класс не хранит ссылки на подклассы и не препятствует сборке мусора для них. Это означает, что подкласс может исчезнуть, если на него больше не останется ссылок:

# drop the reference to subclass, it can be garbage-collected now
c = nil

A.subclasses
# It can be
#  => [#<Class:0x00007f003c77bd78>, D, B]
# ...or just
#  => [D, B]
# ...depending on whether garbage collector was run
superclass → a_super_class or nil Показать исходный код
VALUE
rb_class_superclass(VALUE klass)
{
    RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));

    VALUE *superclasses = RCLASS_SUPERCLASSES(klass);
    size_t superclasses_depth = RCLASS_SUPERCLASS_DEPTH(klass);

    if (klass == rb_cBasicObject) return Qnil;

    if (!superclasses) {
        RUBY_ASSERT(!RCLASS_SUPER(klass));
        rb_raise(rb_eTypeError, "uninitialized class");
    }

    if (!superclasses_depth) {
        return Qnil;
    }
    else {
        VALUE super = superclasses[superclasses_depth - 1];
        RUBY_ASSERT(RB_TYPE_P(super, T_CLASS));
        return super;
    }
}

Возвращает суперкласс класса class или nil.

File.superclass          #=> IO
IO.superclass            #=> Object
Object.superclass        #=> BasicObject
class Foo; end
class Bar < Foo; end
Bar.superclass           #=> Foo

Возвращает nil, если у указанного класса нет родительского класса:

BasicObject.superclass   #=> nil

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

inherited(subclass) Показать исходный код
#define rb_obj_class_inherited rb_obj_dummy1

Обратный вызов, вызываемый при создании подкласса текущего класса.

Пример:

class Foo
  def self.inherited(subclass)
    puts "New subclass: #{subclass}"
  end
end

class Bar < Foo
end

class Baz < Bar
end

Результат:

New subclass: Bar
New subclass: Baz

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

Spec-Zone.ru

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