About

This page contains a single entry from the blog posted on January 27, 2008 3:31 AM.

The previous post in this blog was Rubys Objektmodell.

The next post in this blog is Ideen für die Konfigurationsverwaltung.

Many more can be found on the main index page or by looking through the archives.

Powered by
Movable Type 3.31

« Rubys Objektmodell | Main | Ideen für die Konfigurationsverwaltung »

Ein paar Worte zu Modulen in Ruby

Als Ergänzung zu meinem letzten Eintrag zum Thema "Rubys Objektmodell" folgen ein paar Notizen dazu, wie sich Module in das Gefüge einfügen (müssen sie ja irgendwie, sonst wäre es kein Gefüge ;-))

  • Wird ein Modul mittels include eingebunden, werden alle Modulmethoden zu Instanzmethoden der einbindenden Klasse.
  • Wird ein Modul mittels extend eingebunden, werden alle Modulmethoden zu Klassenmethoden der einbindenden Klasse.
  • es ist (in Rails) durchaus üblich, ein Modul Foo zu definieren, welches dann mit include Foo eingebunden wird, sowie ein Untermodul Foo::ClassMethods, welches mittels extend Foo::ClassMethods eingebunden wird. Diese Praxis habe ich einfach mal so übernommen.

So viel zu den Methoden. Doch was ist mit den Variablen? Wie wir alle wissen, werden Klassenvariablen weitervererbt, Instanzvariablen jedoch nicht (irgendwie logisch...). Aber bei Modulen...?

  • Da ein Modul nicht instanziiert werden kann, kann es auch keine Instanzvariablen (@foo) haben -- ganz einfach. Wird ein Modul mittels include eingebunden, müssen alle @foo's also Instanzvariablen der Objekte werden; wird es mit extend eingebunden, sind es eben Instanzvariablen der Klasse (und NICHT etwa Klassenvariablen oder so...)
  • Klassenvariablen (@@bar) werden bei include einfach übernommen -- sprich, was im Modul eine "Klassen"variable war, wird auch in (den Instanzen) der einbindenden Klasse als Klassenvariable erhalten bleiben. Bei extend jedoch sind alle im Modul definierten Klassenvariablen nur für die im Modul definierten Methoden erreichbar! Alle Versuche, aus dem Kontekt der Klasse (oder einer ihrer Instanzen) an sie heranzukommen, sind bei mir bislang gescheitert.

An einem Beispiel zeigt sich so was immer schön:

module Foo
  @@truth = 42

  def say_the_truth
    p @@truth
  end
end

class Bar
  include Foo
end
Bar.new.say_the_truth # 42 *SMILE*

class FooBar < Bar
  def say_something
    p @@truth
  end
end
FooBar.new.say_something # 42 *SMILE*

class Baz
  extend Foo

  def say_something
    p @@truth
  end
end
Baz.say_the_truth # 42 *SMILE*
Baz.new,say_something # PENG! WUMMS! "NameError: uninitialized class variable @@truth in Baz" ... *Autsch*

Alles klar?

TrackBack

TrackBack URL for this entry:
http://www.innoq.com/movabletype/mt-tb.cgi/2988

Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)