Ruby/Instanzvariable

Aus Scientia
Version vom 8. April 2011, 15:24 Uhr von Alexis Hiemis (Diskussion | Beiträge)

(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Wechseln zu: Navigation, Suche

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"