angus: vererbung

hi

ist vererbun mit perl eigentlich auch möglich? habe ein projekt mit vielen fast gleichen datensätzen und da wäre es mega hilfreich ...

gruss
angus

  1. Hi.

    ist vererbun mit perl eigentlich auch möglich?

    Ja.

    Ich bin zwar leider grottenschlecht in Perl, aber ich hab mal Google bedient:
    http://xlab.net/jochen/perl/perl-5.html - Abschnitt 5.3

    Gruss, Stefan

  2. Hoi,

    ist vererbun mit perl eigentlich auch möglich? habe ein projekt mit vielen
    fast gleichen datensätzen und da wäre es mega hilfreich ...

    Naja, im Grunde schon. Allerdings nur ueber 'Mixin', richtige Vererbung kann Perl
    nicht. Im Grunde verfaehrt Perl so: es sucht die Methode im aktuellen Modul
    (Package). Wenn sie da nicht vorhanden ist, sucht Perl alle in @ISA verzeichneten
    Module ab. Daraus ergibt sich auch die Syntax:

    use strict;
    use vars qw(@ISA);

    @ISA = qw(Baseclass1 Baseclass2);

    Sehr empfehlenswerte Lektuere ist IMHO 'perldoc perltoot', auch zu finden auf
    http://www.perldoc.com/.

    Gruesse,
     CK

    1. Halihallo

      Naja, im Grunde schon. Allerdings nur ueber 'Mixin', richtige Vererbung kann Perl
      nicht. Im Grunde verfaehrt Perl so: es sucht die Methode im aktuellen Modul
      (Package). Wenn sie da nicht vorhanden ist, sucht Perl alle in @ISA verzeichneten
      Module ab. Daraus ergibt sich auch die Syntax:

      @ISA = qw(Baseclass1 Baseclass2);

      Vielleicht noch eine kleine Bemerkung für die, die diese schmerzliche Erfahrung noch nicht gemacht haben:
      @ISA wird depth-first abgearbeitet, also:

      wenn nach einer nicht vorhandenen Methode gesucht wird, wird in diesem Beispiel die Methode zuerst in Baseclass1 gesucht. Ist sie dort auch nicht vorhanden, wird zuerst (also bevor die Suche in Baseclass2 weitergeführt wird) nach der Methode in Baseclasses der Baseclass1 gesucht, erst am Schluss, wenn die ganze hierarchie von Baseclasses von Baseclass1 abgearbeitet wurde, bedient sich perl der baseclass2 und dessen Basisklassen...

      Leider musste ich dies mal schmerzlich feststellen... Zudem finde ich es eigentlich falsch bzw. schlecht implementiert...

      Viele Grüsse

      Philipp

      1. Hi!

        Leider musste ich dies mal schmerzlich feststellen... Zudem finde ich es eigentlich falsch bzw. schlecht implementiert...

        Das Vorkommen mehrerer Eigenschaften mit selbem Namen ist ein grundsaetzliches Problem bei Mehrfachvererbung, das auch schon zwischen zwei Basisklassen auf derselben Vererbungsebene auftreten kann. Ich glaube nicht, dass es dafuer eine allgemeingueltige Loesung gibt oder das man sagen koennte, welche der Suchstrategien als besser einzustufen ist.

        So long

        --
        "Das zwangsweise Speichern aller Daten aus der Nutzung des Internets sollten die Demokraten denen überlassen, die Gründe haben, die Informationsfreiheit zu fürchten."
            -- Bundesbeauftragter für den Datenschutz, Joachim Jacob
               http://www.heise.de/newsticker/data/hob-05.04.01-000/

        1. Halihallo Calocybe

          Leider musste ich dies mal schmerzlich feststellen... Zudem finde ich es eigentlich falsch bzw. schlecht implementiert...

          Das Vorkommen mehrerer Eigenschaften mit selbem Namen ist ein grundsaetzliches Problem bei Mehrfachvererbung, das auch schon zwischen zwei Basisklassen auf derselben Vererbungsebene auftreten kann. Ich glaube nicht, dass es dafuer eine allgemeingueltige Loesung gibt oder das man sagen koennte, welche der Suchstrategien als besser einzustufen ist.

          Wie ist es denn bei anderen Sprachen implementiert?
          Nun, ich kann dein Argument verstehen; es ist wohl auch etwas von der "Funktionsweise" des Programmes abhängig, was mehr Sinn macht. Nur für mein Projekt hatte ich folgendes:

          Klasse Website extends DataNode (speicherung der Daten),
                                 Website::Integrity (Datenintegrität wahren)
                                 Website::Sync (Synchronisation mit anderem S.)
          Eine Andere Klasse, welche vollständig von Website erbt, jedoch auch wieder durch Integrity und Sync erweitert werden

          => @ISA = qw(Website VWebsite::Integrity VWebsite::Sync);

          Also, wenn ich jetzt die Methode checkIntegrity von VWebsite starte, wird er mir die entsprechende Integrity-Methode von Website->Website::Integrity aufrufen, was ja _falsch_ ist, da ich nicht die Integrität der Website sondern der virtuellen Website (VWebsite) testen will... Für meine Anwendung ist also das depth-first-Verfahren schlecht... Mir wäre es viel, viel lieber gewesen, wenn er zuerst in den basisklassen der "gleichen" Ebene gesucht hätte und erst dann in die Tiefe gegangen wäre...
          Aber das Problem habe ich inzwischen gelöst (wenn auch unschön, wie ich gestehen muss). Ich habe die Modul-struktur sehr "logisch" gehalten, deshalb konnte ich dann folgendes machen:

          sub getIntegrityClass {
             my ($class) = @_;
             if ((ref($class) eq 'SCALAR') or (ref($class) eq '')) {
                # seems to be a class
                # do nothing! - $class is already the classname
             } else {
                # seems to be an instance
                $class = ref($class); # now $class is the classname
             }

          # $class is now something like: Anaxus::CampaignGroup::Default
             # but getIntegrityClass should return Anaxus::Integrity::CampaignGroup::Default
             # so, let us insert the 'Integrity::'...

          my @class_dirs = split( /::/, $class );
             shift @class_dirs;   # don't care of the beginning 'Anaxus::'
             unshift @class_dirs, 'Integrity'; # Insert the 'Integrity::'
             unshift @class_dirs, 'Anaxus'; # let's reinsert the top-level 'Anaxus::'
             $class = join( '::', @class_dirs); # rebuild the class-name
             return $class;   # and return it.
          }

          aufgrund des Klassennamens des Objektes bastle ich einfach die entsprechende Namen der entsprechenden Integrity und Sync Module...

          Diese vorher gezeigte Methode befindet sich jeweils in den Basisklassen für Integrität und Synchronisation, da für die Integrität und Sync auch wieder verschiedene Klassen durcheinandererben... Mei, das war'n verzwicktes Zeug... Vererbungen über 7 Ebenen... Hat mir manchmal fast den Hals gebrochen ;)

          Ich hätte natürlich auch einfach in jedes Modul eine Methode einbauen können, welche den gleichen String zurückgiebt, aber das war mir zuviel arbeit (sind ca. 30 Klassen); da mache ich lieber eine Methode an _einem_ Ort, die vielleicht etwas komplizierter ist...

          Viele Grüsse

          Philipp

          1. Hallo,

            Wie ist es denn bei anderen Sprachen implementiert?

            Einige verbieten Mehrfachvererbung, und sind somit ganz einfach aus dem Schneider. Andere verbieten konsequent Doppeldeutigkeiten. Andere zwingen dich dazu, falls Doppeltdeutigkeiten auftreten, exakt zu definierieren, von welcher Basisklasse die betreffende Eigenschaft oder Methode benutzt werden soll.

            Nun, ich kann dein Argument verstehen; es ist wohl auch etwas von der "Funktionsweise" des Programmes abhängig, was mehr Sinn macht. Nur für mein Projekt hatte ich folgendes:

            Klasse Website extends DataNode (speicherung der Daten),
                                   Website::Integrity (Datenintegrität wahren)
                                   Website::Sync (Synchronisation mit anderem S.)
            Eine Andere Klasse, welche vollständig von Website erbt, jedoch auch wieder durch Integrity und Sync erweitert werden

            => @ISA = qw(Website VWebsite::Integrity VWebsite::Sync);

            Also, wenn ich jetzt die Methode checkIntegrity von VWebsite starte, wird er mir die entsprechende Integrity-Methode von Website->Website::Integrity aufrufen, was ja _falsch_ ist, da ich nicht die Integrität der Website sondern der virtuellen Website (VWebsite) testen will... Für meine Anwendung ist also das depth-first-Verfahren schlecht...

            In diesem konkreten Fall müßte eine andere Reihenfolge das gewünschte Ergebnis bringen.

            @ISA = qw(VWebsite::Integrity VWebsite::Sync Website);

            Perl bietet Dir aber auch die Möglichkeit, die Methode vollständig (mit Klasse) anzugeben, wodurch Du auch jederzeit genau spezifizieren kannst, welche Methode Du jetzt verwendest:

            $self->VWebsite::Integrity::checkIntegrity();

            Ich hätte natürlich auch einfach in jedes Modul eine Methode einbauen können, welche den gleichen String zurückgiebt, aber das war mir zuviel arbeit (sind ca. 30 Klassen); da mache ich lieber eine Methode an _einem_ Ort, die vielleicht etwas komplizierter ist...

            Alternativ hättest Du aber auch diese Methode in einer eigenen Klasse implementieren können, von der dann alle anderen erben.

            Grüße
              Klaus

            1. Halihallo

              Also, wenn ich jetzt die Methode checkIntegrity von VWebsite starte, wird er mir die entsprechende Integrity-Methode von Website->Website::Integrity aufrufen, was ja _falsch_ ist, da ich nicht die Integrität der Website sondern der virtuellen Website (VWebsite) testen will... Für meine Anwendung ist also das depth-first-Verfahren schlecht...

              In diesem konkreten Fall müßte eine andere Reihenfolge das gewünschte Ergebnis bringen.

              @ISA = qw(VWebsite::Integrity VWebsite::Sync Website);

              würde Sinn machen, wenn/tät ich nicht von Website erben (SUPER:: nimmt nur das Modul Index 0 aus ISA); aber ja, ich könnte es mit absolutem Modulnamen erben und die Reihenfolge von @ISA ändern...
              Wär natürlich auch ein guter Vorschlag; nur will ich eben genau absolute Modulnamen verhindern, sonst hätte ich ja nie das Problem bekommen.

              Perl bietet Dir aber auch die Möglichkeit, die Methode vollständig (mit Klasse) anzugeben, wodurch Du auch jederzeit genau spezifizieren kannst, welche Methode Du jetzt verwendest:

              $self->VWebsite::Integrity::checkIntegrity();

              ist mir schon klar, nur will ich das nicht immer eintippen müssen ;)
              Sonst hätte ich es doch schon längst so gemacht... Aber erben ist viel schöner, als absolute Modulnamen zu setzen...

              Ich hätte natürlich auch einfach in jedes Modul eine Methode einbauen können, welche den gleichen String zurückgiebt, aber das war mir zuviel arbeit (sind ca. 30 Klassen); da mache ich lieber eine Methode an _einem_ Ort, die vielleicht etwas komplizierter ist...

              Alternativ hättest Du aber auch diese Methode in einer eigenen Klasse implementieren können, von der dann alle anderen erben.

              Hab ich doch:

              Integrity::Base => getIntegrityClass, getIntegrityInstance
              Integrity::Website extends Integrity::Base
              Integirty::VWebsite extends Integrity::Base
              Integirty::Page extends Integrity::Base
              ...

              Sync::Base => getSynchronisationClass, getSynchronisationInstance
              Sync::Website extends Sync::Base
              ...

              die genannte Methode ist in einer Klasse, welche von allen anderen "zwecksgleichen" Klassen geerbt wird.

              ---
              im Übrigen bin ich ziemlich auf SUPER:: angewiesen und kann die Methoden nicht über absolute Modulnamen ansprechen, da ich sonst das ganze OOP-Konzept der Webapplikation durcheinander bringen würde. Das ganze Ding ist ziemlich kompliziert (aber schön!! ;)) aufgebaut, deshalb mach ich jetzt auch kein Beispiel (es sei denn es wäre gewünscht); du musst mir einfach glauben, dass ich auf SUPER:: angewiesen bin (ich hätte auch eine Lösung gefunden, wäre dem nicht so)...
              ---

              Viele Grüsse

              Philipp

              PS: Ja, ja, was man nicht alles in Kauf nimmt, um "schön" zu programmieren... ;)

              1. Halihallo


                im Übrigen bin ich ziemlich auf SUPER:: angewiesen und kann die Methoden nicht über absolute Modulnamen ansprechen, da ich sonst das ganze OOP-Konzept der Webapplikation durcheinander bringen würde. Das ganze Ding ist ziemlich kompliziert (aber schön!! ;)) aufgebaut, deshalb mach ich jetzt auch kein Beispiel (es sei denn es wäre gewünscht); du musst mir einfach glauben, dass ich auf SUPER:: angewiesen bin (ich hätte auch eine Lösung gefunden, wäre dem nicht so)...

                Kommando zurück... Ich wäre in der Tat nicht auf SUPER:: angewiesen; da hab ich einen Denkfehler begangen.
                Ich dachte an folgende Problematik:
                wenn ich aus einer Instanz von VWebsite getPages aufrufe, soll die Methode mir auch eine Instanz von VPageList liefern und nicht PageList (da die Methode früher von Website geerbt wurde; heute muss die Methode auch in VPage sein)... Aber das wird nicht über SUPER:: geregelt.
                Nochmals danke für deine Vorschläge, Klaus.

                Viele Grüsse

                Philipp

              2. Hallo,

                (SUPER:: nimmt nur das Modul Index 0 aus ISA);

                Wie Du in einem anderen Posting schon sagest, geht Perl die geerbeten Module der Reihe nach durch, um eine Methode zu finden. Nicht anders verhält es sich um eine SUPER::Methode zu suchen. Daher wäre eine Umstellung der geerbeten Module durchaus möglich, ohne daß SUPER::Websitemethode() nicht funktionieren würde.

                PS: Ja, ja, was man nicht alles in Kauf nimmt, um "schön" zu programmieren... ;)

                ICh bin mir allerdings nicht sicher, ob mögliche Mehrdeutigkeiten noch als schön ebzeichnet werden kann;-)

                Grüße
                  Klaus

                1. Halihallo Klaus

                  (SUPER:: nimmt nur das Modul Index 0 aus ISA);

                  Wie Du in einem anderen Posting schon sagest, geht Perl die geerbeten Module der Reihe nach durch, um eine Methode zu finden. Nicht anders verhält es sich um eine SUPER::Methode zu suchen. Daher wäre eine Umstellung der geerbeten Module durchaus möglich, ohne daß SUPER::Websitemethode() nicht funktionieren würde.

                  Der Konstruktor new ist ja in jeder Klasse vorhanden... Wenn ich jetzt also die Reihenfolge von @ISA verändere, nimmt es mir den Falschen (muss ja)... Das Problem mit SUPER:: bezog sich auf die Konstruktoren (sorry, hatte ich nicht erwähnt).

                  PS: Ja, ja, was man nicht alles in Kauf nimmt, um "schön" zu programmieren... ;)

                  ICh bin mir allerdings nicht sicher, ob mögliche Mehrdeutigkeiten noch als schön ebzeichnet werden kann;-)

                  Och, wenn eine gewisse Logik dahintersteckt schon ;-)
                  Wenn man weiss, wie ISA intern funktioniert, kann man ganz nette Sachen machen. Aber leider funktionierte es in meinem Fall eben genau nicht so, wie ich es gewünscht hätte... Das ziel ist es ja eben _genau_ diejenige Methode zufinden, welche auch für das entsprechende "Objekt" (nicht im OOP-Sinn, sondern z. B. Website oder Page) zuständig ist; auch _wenn_ es den selben Namen hat.

                  Viele Grüsse

                  Philipp

                  PS: Irgendwann geh ich dann auch mal schlafen ;)