Ruby/Instanzvariable
Syntax
Schlüsselwörter
Beschreibung
Instanzvariablen sind Variablen, die an ein Objekt gebunden sind. Sie leben solange wie das Objekt, an dem sie gebunden sind. Normalerweise werden Instanzvariablen verwendet um Eigenschaften bzw. Attribute eines Objektes darzustellen.
Instanzvariablen sind daran zu erkennen, dass ihre Namen mit einem @ beginnen (wobei das @ Zeichen für Attribut steht).
class Person def initialize name @name = name end def vorstellen print "ich heiße #{@name}" end end alex = Person.new("Alex") aluxes = Person.new("Aluxes") alex.vorstellen #=> ich heiße Alex aluxes.vorstellen #=> ich heiße Aluxes
In diesem Beispiel wird eine Klasse Person definiert die in ihrer initialize Methode eine Instanzvariable @name setzt. In der Methode vorstellen wird dann auf den Inhalt dieser Variable zugegriffen. Dieses Beispiel zeigt bereits zwei grundlegende Eigenschaften von Instanzvariablen:
- alle Methoden eines Objektes haben Zugriff auf dieselben Instanzvariablen
- verschiedene Objekte (hier alex und aluxes) können völlig unterschiedliche Belegungen für ihre Instanzvariablen haben
Lokale Variablen beispielsweise wären nicht in der Lage sowohl in der Methode initialize als auch in der Methode referenziert zu werden, da eine lokale Variable immer nur in einem Scope gültig ist. Globale Variablen hingegen wären zwar in der Lage in beiden Methoden benutzt zu werden, allerdings könnte man nicht gleichzeitig zwei verschiedene Instanzen mit unterschiedlicher Belegung der Variablen haben. Hierzu sind nur Instanzvariablen in der Lage.
Weitere Eigenschaften von Instanzvariablen:
- Instanzvariablen können jederzeit definiert und belegt werden. Auch wenn das Objekt schon lange existiert.
- wurde eine Instanzvariable noch nicht mit einem Wert belegt, so zeigt sie auf den Wert nil.
- Instanzvariablen sind immer objektspezifisch. Zwei Objekte derselben Klasse können also unterschiedliche Instanzvariablen haben. Allerdings werden Instanzvariablen normalerweise in Methoden (meistens in der initialize Methode) definiert, so dass zwei Objekte der gleichen Klasse, welche üblicherweise auch dieselben Methoden kennen, meistens auch die selben Instanzvariablen kennen.
- Jedes Objekt darf Instanzvariablen haben. Sowohl Instanzen nutzerdefinierter Klassen, als auch Instanzen von Standardklassen wie Array oder String. Selbst immediate Objekte wie Fixnum, Symbole etc. dürfen Instanzvariablen haben.
- Auch Klassen dürfen Instanzvariablen besitzen. Als Beispiel, siehe Cache
Zugriff auf Instanzvariablen von außen
Auf eine Instanzvariable hat man immer nur innerhalb des Objektes (das heißt innerhalb von Methoden, die das Objekt ausführen kann) Zugriff. Will man auch von außen auf die Instanzvariable zugreifen, muss man sich entsprechende Zugriffsmethoden schreiben:
class Person def initialize name @name = name end def umbenennen neuer_name @name = neuer_name end def vorstellen @name end end alex = Person.new("Alex") alex.vorstellen #=> Alex alex.umbenennen("Aluxes") alex.vorstellen #=> Aluxes
Da Ruby Methodennamen erlaubt, die mit einem = enden, ist auch folgende Schreibweise möglich:
class Person def initialize name @name = name end def name= neuer_name @name = neuer_name end def name @name end end alex = Person.new("Alex") alex.name #=> Alex alex.name = "Aluxes" #=> ruft die Methode Person#name= auf alex.name #=> Aluxes
attr_reader, attr_writer, attr_accessor
Da es häufig notwendig ist Zugriffsmethoden für Instanzvariablen zu schreiben, bietet Ruby drei Hilfsmethoden die solche Zugriffsmethoden anlegen.
attr_reader legt eine Methode an, die Lesezugriff auf eine Instanzvariable ermöglicht. attr_writer legt eine Methode an, die Schreibzugriff auf eine Instanzvariable ermöglicht. attr_accessor legt sowohl eine Lesemethode als auch eine Schreibmethode an. Die Methoden bekommen als Parameter den Namen der Instanzvariable (ohne das @). Üblicherweise gibt man den Namen als Symbol an.
class Person attr_accessor :name end alex = Person.new alex.name = "Alex" print alex.name #=> Alex
Es ist auch möglich mehrere Zugriffsmethoden zu erzeugen, in dem man mehr als einen Namen angibt.
class Person attr_accessor :vorname, :nachname attr_reader :alter attr_writer :waffe def initialize vorname, nachname, alter @vorname = vorname @nachname = nachname @alter = alter @waffe = "keine" end end alex = Person.new("Alex", "der Held", 14) alex.vorname = "Aluxex" print alex.vorname #=> Aluxes print alex.nachname #=> der Held alex.alter #=> 14 alex.waffe = "Morgenstern"