класс Class
Расширяет любой Class, добавляя метод json_creatable?.
Классы в 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)-----------... Публичные методы класса
Исходный код
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 (super != rb_cBasicObject && !RCLASS_SUPER(super)) {
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
}
}
RCLASS_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"
Присвойте классу константу (имя, начинающееся с большой буквы), если хотите использовать его как обычный класс.
Публичные методы экземпляра
Исходный код
static VALUE
rb_class_alloc_m(VALUE klass)
{
rb_alloc_func_t allocator = class_get_alloc_func(klass);
if (!rb_obj_respond_to(klass, rb_intern("allocate"), 1)) {
rb_raise(rb_eTypeError, "calling %"PRIsVALUE".allocate is prohibited",
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
Исходный код
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
Исходный код
# File ext/json/lib/json/common.rb, line 893 def json_creatable? respond_to?(:json_create) end
Возвращает true, если этот класс можно использовать для создания экземпляра из сериализованной JSON строки. Класс должен реализовывать метод класса json_create, который принимает в качестве первого параметра хэш. Хэш должен содержать необходимые данные.
Исходный код
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.
Исходный код
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
Исходный код
VALUE
rb_class_superclass(VALUE klass)
{
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
VALUE super = RCLASS_SUPER(klass);
if (!super) {
if (klass == rb_cBasicObject) return Qnil;
rb_raise(rb_eTypeError, "uninitialized class");
}
if (!RCLASS_SUPERCLASS_DEPTH(klass)) {
return Qnil;
}
else {
super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1];
RUBY_ASSERT(RB_TYPE_P(klass, 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
Приватные методы экземпляра
Исходный код
#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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.