Die Programmiersprache Ruby

Blog| Forum| Wiki  

Dass in Ruby alles ein Objekt ist, ist ja relativ bekannt. Dass in Ruby jedoch jedes Objekt auch ein individuelles Objekt ist, gehört vermutlich nicht zum allgemeinen Wissen über Ruby. Aber gerade dieses Konzept der Individualität von Objekten macht Ruby noch ein gutes Stück natürlicher; denn schließlich hat auch nicht jeder Mensch die gleichen Talente. Diese individuellen Fähigkeiten von Objekten werden in Ruby mithilfe sogenannter Singleton- oder Eigenklassen dargestellt (der erste Begriff ist dabei der gängigere, daneben wurde vor allem von _why der Begriff »Metaklasse« benutzt) und fast jedes Objekt in Ruby besitzt eine solche. Ausnahmen sind nur Immediate Values wie Fixnums oder Symbole. Das Konzept ist ganz einfach vorgestellt:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Foo
  
  def bar
    "bar"
  end
  
end
#Soweit nichts neues. Jede Instanz von Foo beherrscht damit die Methode #bar. 
x = Foo.new
y = Foo.new
puts x.bar #=> bar
puts y.bar #=> bar
#Nun kommen Singletons ins Spiel. Ich gebe x hier eine Fähigkeit, 
#die y nicht besitzt. 
def x.baz
  "baz"
end
puts x.baz #=> baz
puts y.baz #=> NoMethodError
#Und trotzdem sind beides nach wie vor Foos. 
puts x.kind_of? :Foo #=> true
puts y.kind_of? :Foo #=> true

Wie wir sehen, können wir also Singletonmethoden definieren, indem wir das Objekt, dass diese Methode »erlernen« soll, angeben: def object.method.

Singletonklassen

Nun ist ja die ganze Zeit von Singletonklassen die Rede, aber bis hierhin haben wir nur Singletonmethoden kennen gelernt. Methoden werden bekanntlicherweise ja immer in Klassen (oder Modulen) definiert. Wo ist also die Klasse, die die Methode baz aus dem obigen Beispiel beinhaltet? Zum Öffnen der Singletonklasse eines Objektes bietet Ruby eine spezielle Syntax. Wir hätten baz auch so definieren können:

1
2
3
4
5
6
class << x
  def baz
    "baz"
  end
end
puts x.baz #=> baz

class << object öffnet die Singletonklasse eines Objektes. Dies ist eine der wenigen Stellen in Ruby, in denen statt Syntax keine Methode angewandt werden kann. Es gibt kein Object#singleton_class wie es ein Object#class gibt. Das Problem lässt sich jedoch leicht kompensieren:

1
2
3
4
5
6
7
8
9
class Object
  
  def singleton_class
    class << self
      self
    end
  end
  
end

_why hat diese Technik zum Erstellen eines meta_evals benutzt, um ein eval im Kontext der Singletonklasse eines Objektes auszuführen (vgl. auch intstance_eval).

Klassenmethoden

Vielleicht ist es ja dem ein oder anderen schon im obersten Abschnitt beim Definieren von baz für x aufgefallen: Die Syntax ähnelt doch sehr der für Klassenmethoden. Tja, sie ähnelt der Syntax nicht nur, es ist exakt die selbe. Denn Klassenmethoden sind nichts anderes als Singletonmethoden auf dem Objekt der Klasse.

1
2
3
4
5
6
7
class Foo
  
  def self.bar
    "bar"
  end
  
end

Ist das gleiche wie:

1
2
3
4
5
6
7
8
9
10
11
class Foo
  
  class << self #oder auch class << Foo
    
    def bar
      "bar"
    end
  
  end
  
end

Der Begriff

Als letztes noch die Frage: »Warum heißt das denn Singleton?«

1
2
3
x = "a"
singleton = x.singleton_class
y = singleton.new #=> TypeError: can't create instance of singleton class

Weil sie eben nur einmal instanziiert werden kann und deshalb single, also einmalig, ist.