class Class
Klassen in Ruby sind First-Class-Objekte – jede ist eine Instanz der Klasse Class.
Normalerweise erstellst du eine neue Klasse mit
class Name # some code describing the class behavior end
Wenn eine neue Klasse erstellt wird, wird ein Objekt vom Typ Class initialisiert und einer globalen Konstante (in diesem Fall Name) zugewiesen.
Wenn Name.new aufgerufen wird, um ein neues Objekt zu erstellen, wird standardmäßig die new-Methode in Class ausgeführt. Dies kann durch Überschreiben von new in Class demonstriert werden.
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
ergibt
Creating a new Name
Klassen, Module und Objekte sind miteinander verbunden. In der folgenden Abbildung stellen die vertikalen Pfeile die Vererbung dar und die Klammern Metaklassen. Alle Metaklassen sind Instanzen der Klasse „Class“.
+---------+ +-...
| | |
BasicObject-----|-->(BasicObject)-------|-...
^ | ^ |
| | | |
Object---------|----->(Object)---------|-...
^ | ^ |
| | | |
+-------+ | +--------+ |
| | | | | |
| Module-|---------|--->(Module)-|-...
| ^ | | ^ |
| | | | | |
| Class-|---------|---->(Class)-|-...
| ^ | | ^ |
| +---+ | +----+
| |
obj--->OtherClass---------->(OtherClass)-----------...
Öffentliche Klassenmethoden
Source
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;
}
Erstellt eine neue anonyme (unbenannte) Klasse mit der angegebenen Oberklasse (oder Object, wenn kein Parameter angegeben wird). Du kannst einer Klasse einen Namen geben, indem du das Klassenobjekt einer Konstante zuweist.
Wenn ein Block angegeben wird, wird das Klassenobjekt übergeben und der Block wird im Kontext dieser Klasse wie bei class_eval ausgewertet.
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"
Weise die Klasse einer Konstante zu (Name beginnt mit Großbuchstaben), wenn du sie wie eine normale Klasse behandeln möchtest.
Öffentliche Instanzmethoden
Source
static VALUE
rb_class_alloc(VALUE klass)
{
rb_alloc_func_t allocator = class_get_alloc_func(klass);
return class_call_alloc_func(allocator, klass);
}
Reserviert Speicher für ein neues Objekt der Klasse von *class* und ruft nicht initialize für die neue Instanz auf. Das zurückgegebene Objekt muss eine Instanz von *class* sein.
klass = Class.new do def initialize(*args) @initialized = true end def initialized? @initialized || false end end klass.allocate.initialized? #=> false
Source
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);
}
Gibt das Objekt zurück, für das der Empfänger die Singleton-Klasse ist.
Löst einen TypeError aus, wenn die Klasse keine Singleton-Klasse ist.
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
Source
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;
}
Ruft allocate auf, um ein neues Objekt der Klasse von *class* zu erstellen, und ruft dann die initialize-Methode dieses Objekts auf und übergibt ihm *args*. Dies ist die Methode, die immer aufgerufen wird, wenn ein Objekt mit .new erstellt wird.
Source
VALUE
rb_class_subclasses(VALUE klass)
{
return class_descendants(klass, true);
}
Gibt ein Array von Klassen zurück, bei denen der Empfänger die direkte Oberklasse der Klasse ist, ausgenommen Singleton-Klassen. Die Reihenfolge des zurückgegebenen Arrays ist nicht definiert.
class A; end class B < A; end class C < B; end class D < A; end A.subclasses #=> [D, B] B.subclasses #=> [C] C.subclasses #=> []
Anonyme Unterklassen (nicht mit einer Konstante verbunden) werden ebenfalls zurückgegeben
c = Class.new(A) A.subclasses # => [#<Class:0x00007f003c77bd78>, D, B]
Beachte, dass die Elternklasse keine Referenzen auf Unterklassen hält und sie nicht am Garbage Collecting hindert. Das bedeutet, dass die Unterklasse verschwinden kann, wenn alle Referenzen darauf gelöscht werden.
# 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
Source
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;
}
}
Gibt die Oberklasse von *class* oder nil zurück.
File.superclass #=> IO IO.superclass #=> Object Object.superclass #=> BasicObject class Foo; end class Bar < Foo; end Bar.superclass #=> Foo
Gibt nil zurück, wenn die angegebene Klasse keine Elternklasse hat
BasicObject.superclass #=> nil
Private Instanzmethoden
Source
#define rb_obj_class_inherited rb_obj_dummy1
Callback, der aufgerufen wird, wenn eine Unterklasse der aktuellen Klasse erstellt wird.
Beispiel
class Foo def self.inherited(subclass) puts "New subclass: #{subclass}" end end class Bar < Foo end class Baz < Bar end
ergibt
New subclass: Bar New subclass: Baz