pl: Instanz um Methoden errweitern

0 53

Instanz um Methoden errweitern

pl
  • php
  1. 0
    Tabellenkalk
    1. 0
      pl
  2. 1
    1unitedpower
    1. 0
      pl
      1. 0
        1unitedpower
        1. 0
          Rolf B
          1. 0
            1unitedpower
            1. 0
              Rolf B
              1. 0
                pl
        2. 0
          pl
          1. 0
            1unitedpower
            1. 0
              Matthias Apsel
            2. 0
              pl
              1. 0
                1unitedpower
                1. 0
                  pl
                  1. 2
                    1unitedpower
              2. 0
                pl
                1. 0
                  1unitedpower
            3. 0
              Der Martin
              1. 1
                Christian Kruse
                1. 0
                  pl
                  1. 0
                    Christian Kruse
                2. 0
                  Rolf B
                  1. 0
                    Christian Kruse
                    1. 0
                      Rolf B
                      1. 0
                        Christian Kruse
                        1. 0
                          1unitedpower
                      2. 0
                        1unitedpower
                        1. 0
                          Christian Kruse
                          1. 0
                            1unitedpower
                            1. 0
                              Christian Kruse
                              • elixir
                  2. 0
                    pl
                    1. 0
                      Christian Kruse
                    2. 0
                      pl
                      1. 0
                        Matthias Apsel
              2. 0
                pl
              3. 0
                1unitedpower
              4. 0
                pl
                1. 1
                  Rolf B
                  1. 0
                    pl
                  2. 0
                    pl
  3. 0
    Rolf B
    1. 0
      pl
      1. 2
        Rolf B
        1. -2
          pl
          1. 0
            Christian Kruse
          2. 0
            pl
            • perl
            • php
  4. 0
    pl
    1. 0
      Rolf B
      1. 0
        pl
        1. 0
          Mitleser
      2. 0
        pl

Moin,

was in Perl geht:

require "Mail";
$this->sendmail(); 

d.h., die mit der nachgeladenen Datei eingebrachten Funktionen kann man mit $this aufrufen weil sie zum Namespace der aktuellen Klasse gehören.

In PHP jedoch ist es nicht möglich diese Funktionen mit $this aufzurufen. Wie löst PHP dieses Problem? Geht das evntl. in V > 5.3?

MFG

  1. Hallo,

    dein Betreff passt nicht zur gestellten Frage, bzw. zu deinem „Problem“.

    Um eine Methode eines Objektes aufzurufen, musst du in der Regel erstmal ein solches instanziieren.

    Gruß
    Kalk

    1. Hallo,

      dein Betreff passt nicht zur gestellten Frage, bzw. zu deinem „Problem“.

      Um eine Methode eines Objektes aufzurufen, musst du in der Regel erstmal ein solches instanziieren.

      Die Instanz liegt ja vor. Wie gewöhnlich in $this

      MFG

  2. In PHP jedoch ist es nicht möglich diese Funktionen mit $this aufzurufen. Wie löst PHP dieses Problem? Geht das evntl. in V > 5.3?

    Mit Traits.

    1. In PHP jedoch ist es nicht möglich diese Funktionen mit $this aufzurufen. Wie löst PHP dieses Problem? Geht das evntl. in V > 5.3?

      Mit Traits.

      Ein Beispiel wäre gut. Du hast $this als Instanz der Klasse Egal und definierst eine Methode extern() in einem Trait den Du einbindest. Nun sollte man $this->extern() aufrufen können.

      Kannst Du in dieser Methode extern() auch weitere Methoden der Klasse Egal mit $this aufrufen?

      MFG

      1. Ein Beispiel wäre gut.

        In der Doku findest du auch Beispiele.

        Kannst Du in dieser Methode extern() auch weitere Methoden der Klasse Egal mit $this aufrufen?

        Hast du schon eine Suchmaschine gefragt oder es zumindest mal ausprobiert?

        1. Hallo 1unitedpower,

          kann man einen Trait nachträglich an eine Klasse ankleben?

          Normalerweise sagt die Klasse doch use MailTrait als Teil der class Deklaration

          Rolf

          --
          sumpsi - posui - clusi
          1. kann man einen Trait nachträglich an eine Klasse ankleben?

            Normalerweise sagt die Klasse doch use MailTrait als Teil der class Deklaration

            Was meinst du genau mit nachträglich? Wenn man die use-Deklaration nicht statisch benutzen möchte, dann könnte man zur Laufzeit eine neue Klasse erzeugen, die von der ursprünglichen Klasse erbt und den(?) Trait verwendet:

            
            class Foo {
            }
            
            trait Bar {
            }
            
            $foobar = new class extends Foo {
                use Bar;
            }
            

            Aber mir fällt dafür kein sinnvolles Anwendungsbeispiel ein.

            1. Hallo 1unitedpower,

              $foobar = new class extends Foo {
                  use Bar;
              }
              

              Das sieht gruselig aus. Da haben sie für PHP 7 aber schwer bei Java abgeguckt...

              Tatsächlich, auf diese Weise könnte man die mail-Methode aus einem Mailer-Trait hinzumischen. Aber nur in dieser anonymen Subklasse. Und nicht mit PHP 5.3 😉

              Rolf

              --
              sumpsi - posui - clusi
              1. $foobar = new class extends Foo {
                    use Bar;
                }
                

                Das sieht gruselig aus.

                Das ist kein Code den ich morgen noch verstehen würde wenn ich den heute schreibe. MFG

        2. Ein Trait ist ein Begriff aus der objektorientierten Programmierung und beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, ähnlich einer Klasse. Desweiteren können diese Methoden von Instanzen beliebiger Klassen benutzt werden. Ein Trait selbst ist nicht instanziierbar.

          Anhand dieser Definition (wiki) ist es ja genau das was ich beabsichtige.

          In der Doku findest du auch Beispiele.

          Anhand derer erschließt es sich mir leider nicht inwiefern man mit dem was PHP unter einem Trait versteht obenstehendes Ziel erreicht.

          MFG

          1. Ein Trait ist ein Begriff aus der objektorientierten Programmierung und beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, ähnlich einer Klasse. Desweiteren können diese Methoden von Instanzen beliebiger Klassen benutzt werden. Ein Trait selbst ist nicht instanziierbar.

            Anhand dieser Definition (wiki) ist es ja genau das was ich beabsichtige.

            In der Doku findest du auch Beispiele.

            Anhand derer erschließt es sich mir leider nicht inwiefern man mit dem was PHP unter einem Trait versteht obenstehendes Ziel erreicht.

            Dann geh die Definition dochmal Satz für Satz durch:

            Ein Trait ist ein Begriff aus der objektorientierten Programmierung und beschreibt eine wiederverwendbare Sammlung von Methoden und Attributen, ähnlich einer Klasse.

            trait Foo {
               public int attribut = 42; // <-- Das ist ein Attribut
            
               public methode () : void {} // <-- Das ist eine Methode
            } // Das Trait ist eine Sammlung von Methoden und Attributen
            

            Desweiteren können diese Methoden von Instanzen beliebiger Klassen benutzt werden.

            class A {use Foo;} // <-- Das ist eine Klasse
            class B {use Foo;} // <-- Das ist auch eine Klasse
            
            $a = new A(); // <-- Das ist eine Instanz der Klasse A
            $b = new B(); // <-- Das ist eine Instanz der Klasse B
            
            $a->attribut; // Die Instanz von A kann Attribute des Traits verwenden
            $a->methode(); // Die Instanz von A kann Methoden des Traits verwenden
            
            $b->attribut; // Die Instanz von B kann ebenfalls Attribute des Traits verwenden
            $b->methode(); // Die Instanz von B kann ebenfalls Methoden des Traits verwenden
            

            Ein Trait selbst ist nicht instanziierbar.

            $foo = new Foo(); // Das geht nicht. Das Trait kann nicht instanziiert werden.
            
            1. Hallo 1unitedpower,

              class A {use Foo;} // <-- Das ist eine Klasse
              

              A? Foo? 😉

              Aber schön erklärt.

              Bis demnächst
              Matthias

              --
              Du kannst das Projekt SELFHTML unterstützen,
              indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
            2. Ahh jetzt verstehe. Löst aber das Problem nicht ganz: Es muss auch einer Möglichkeit geben, in der extern definierten Methode (Trait) auf die Eigenschaften der Instanz welche diese Metode aufruft, zugreifen zu können.

              Also

              $a->methode(); 
              // Die Instanz von A kann Methoden des Traits verwenden
              

              kann man innerhalb methode() auf die Eigenschaften von $a zugreifen und kann $a innerhalb von methode() weitere Methoden aufrufen die in Traits deklariert sind?

              MFG

              1. kann man innerhalb methode() auf die Eigenschaften von $a zugreifen und kann $a innerhalb von methode() weitere Methoden aufrufen die in Traits deklariert sind?

                Selbe Gegenfrage wie zuvor: Hast du schon eine Suchmaschine gefragt oder es zumindest mal ausprobiert?

                1. kann man innerhalb methode() auf die Eigenschaften von $a zugreifen und kann $a innerhalb von methode() weitere Methoden aufrufen die in Traits deklariert sind?

                  Selbe Gegenfrage wie zuvor: Hast du schon eine Suchmaschine gefragt oder es zumindest mal ausprobiert?

                  Meine PHP Version kennst Du?

                  Und es kommt nochwas dazu: Die externen Methoden sollen automatisch aufgerufen werden. Also in __call(). Diesen ganzen Komplex kann nur ein Praktiker kennen der schonmal was damit gemacht und auch darüber geschrieben hat. Und auch da macht eine Suchmaschine keinen Sinn, deswegen frag ich ja hier.

                  MFG

                  1. Meine PHP Version kennst Du?

                    Du weißt welches Jahr wir schreiben?

              2. Ahh jetzt verstehe. Löst aber das Problem nicht ganz: Es muss auch einer Möglichkeit geben, in der extern definierten Methode (Trait) auf die Eigenschaften der Instanz welche diese Metode aufruft, zugreifen zu können.

                Also

                $a->methode(); 
                // Die Instanz von A kann Methoden des Traits verwenden
                

                kann man innerhalb methode() auf die Eigenschaften von $a zugreifen und kann $a innerhalb von methode() weitere Methoden aufrufen die in Traits deklariert sind?

                Nach meiner letzten Recherche ist das nicht möglich. PHP Traits stellen nur statische Methoden bereit, hab ich grad eben gelesen. Nette Spielerei 😉

                MFG

                1. Nach meiner letzten Recherche ist das nicht möglich. PHP Traits stellen nur statische Methoden bereit, hab ich grad eben gelesen.

                  Dann ist deine Recherche wohl nicht gründlich gewesen.

            3. Hallo,

              trait Foo {
                 public int attribut = 42; // <-- Das ist ein Attribut
              
                 public methode () : void {} // <-- Das ist eine Methode
              } // Das Trait ist eine Sammlung von Methoden und Attributen
              

              an dieser Stelle muss ich mal ketzerisch (oder naiv?) fragen, warum man in der OOP Funktionen einer Klasse nicht mehr Funktionen nennt, sondern Methoden. Das ist mir schon vor vielen Jahren aufgefallen und irgendwie gegen den Strich gegangen, aber eine einleuchtende Erklätung konnte mir noch niemand anbieten.

              In C++ beispielsweise ist eine Methode auch nur eine Funktion, nur dass sie indirekt über die Methodentabelle der Klasse aufgerufen wird und als erstes implizites Argument einen Zeiger auf die Instanz (in C++: self) übergeben bekommt.
              Also warum ein eigener Fachbegriff?

              Ciao,
               Martin

              --
              Ich stamme aus Ironien, einem Land am sarkastischen Ozean.
              1. Hallo Martin,

                an dieser Stelle muss ich mal ketzerisch (oder naiv?) fragen, warum man in der OOP Funktionen einer Klasse nicht mehr Funktionen nennt, sondern Methoden. […]

                In C++ beispielsweise ist eine Methode auch nur eine Funktion, nur dass sie indirekt über die Methodentabelle der Klasse aufgerufen wird und als erstes implizites Argument einen Zeiger auf die Instanz (in C++: self) übergeben bekommt.
                Also warum ein eigener Fachbegriff?

                Weil die Nomenklatur genau diesen Unterschied kennzeichnet. Eine Methode ist eine Funktion, die an ein Objekt oder eine Klasse gebunden ist und deshalb Zugriff auf die internen Datenstrukturen (inklusive andere Methoden) des Objekts oder der Klasse hat.

                Oder, um es noch mehr zu simplifizieren: eine Methode ist an ein Objekt oder eine Klasse gebunden. Eine Funktion ist unabhängig von einem Objekt oder einer Klasse. Das ist alles.

                Freundliche Grüße,
                Christian Kruse

                1. Eine Funktion ist unabhängig von einem Objekt oder einer Klasse.

                  In Perl ist das nicht zutreffend. Da gibt es nämlich immer eine Klasse main und eine Klasse von der alle Klassen erben (UNIVERSAL). Da kann man sogar Builtinfunktionen überlagern weil das eben auch Methoden sind.

                  MFG

                  (Dass man nicht jede Builtinfunktion überlagern kann hat andere Gründe)

                  1. Hallo pl,

                    Eine Funktion ist unabhängig von einem Objekt oder einer Klasse.

                    In Perl ist das nicht zutreffend.

                    Doch, ist es. Du kannst in Perl eine Funktion ggfls. auch als Methode nutzen, aber sie muss damit umgehen können und um den Umstand wissen.

                    Da gibt es nämlich immer eine Klasse main und eine Klasse von der alle Klassen erben (UNIVERSAL).

                    Du wirfst Package und Class durcheinander. Und nein, das ist nicht dasselbe. Aus der Perldoc: „In Perl, any package can be a class. The difference between a package which is a class and one which isn't is based on how the package is used.“ – Hervorhebung von mir. Nur weil das Keyword package dort steht ist es keine Klasse. Und umgekehrt, nur weil das Keyword package dort steht ist es nicht keine Klasse.

                    Da kann man sogar Builtinfunktionen überlagern weil das eben auch Methoden sind.

                    Du kannst sie überschreiben, weil Perl eine dynamische Sprache ist.

                    Freundliche Grüße,
                    Christian Kruse

                2. Hallo Christian,

                  eigentlich können wir uns ja glücklich schätzen, dass man die Dinger nicht „Empfänger“ (receiver) oder „Kanäle“ genannt hat. Denn die Idee von OOP ist ja eigentlich, dass man einen Schwarm von Objekten hat, die sich gegenseitig Botschaften schicken. Hinzu kommen noch Verknüpfungsbeziehungen (Assoziationen) wie Aggregation, Komposition und Vererbung. Und ein Objekt braucht Empfänger, um Botschaften zu verstehen. Oder verschiedene Kanäle, auf denen es unterschiedliche Typen von Botschaften bekommt.

                  Das, was man bspw. in C++ gemacht hat, nämlich Objekte auf Strukturen, Botschaften auf Funktionsaufrufe und Vererbung auf Schachtelung abzubilden, ist eine Möglichkeit wie man OOP betreiben kann. Vermutlich die performanteste, darum machen es alle Sprachen, die ich kenne, so. Aber es ist nicht die einzige.

                  Insofern ist es für mich schon ok, dass die Dinger nicht Funktionen heißen, sondern einen eigenen Namen haben. Der Begriff „Methode“ kommt vermutlich daher, dass er semantisch mit "Prozedur" verwandt ist. Und "prozedurale Programmierung" sagt uns ja allen noch was.

                  Rolf

                  --
                  sumpsi - posui - clusi
                  1. Hallo Rolf,

                    eigentlich können wir uns ja glücklich schätzen, dass man die Dinger nicht „Empfänger“ (receiver) genannt hat.

                    Der Empfänger wäre nicht die Methode, sondern das Objekt 😀 die Methode wäre die Nachricht, die man an das Objekt schickt.

                    Es gibt übrigens durchaus Programmiersprachen, die dieses Paradigma versuchen umzusetzen. Die berüchtigste wäre wohl Smalltalk. Aber auch modernere Sprachen wie Obj-C oder Ruby bedienen sich dieses Bildes.

                    Das, was man bspw. in C++ gemacht hat, nämlich Objekte auf Strukturen, Botschaften auf Funktionsaufrufe und Vererbung auf Schachtelung abzubilden, ist eine Möglichkeit wie man OOP betreiben kann. Vermutlich die performanteste, darum machen es alle Sprachen, die ich kenne, so. Aber es ist nicht die einzige.

                    Du kennst mindestens eine Sprache, deren OO-Konzept anders ist als das von C++. JavaScript. 😀

                    Freundliche Grüße,
                    Christian Kruse

                    1. Hallo Christian,

                      die Methode wäre die Nachricht, die man an das Objekt schickt.

                      Äh, nein. Zumindest habe ich das in Smalltalk anders gelernt. Die Botschaft ist das, was der Aufrufer abschickt (Name+Daten) und die Methode ist ein Feature des Empfängerobjekts, das für diese Botschaft zuständig ist.

                      Du kennst mindestens eine Sprache, deren OO-Konzept anders ist als das von C++. JavaScript.

                      Das Vererbungskonzept ist anders, ja. Objekte sind Strukturen (ok, dynamische Key-Value Listen) und Methoden-Aufrufe sind Funktionsaufrufe. D.h. der Kern der Kommunikation ist immer noch der gleiche.

                      Eine OOP Sprache mit echtem Messaging, das stelle ich mir so vor, dass jedes Objekt in einem eigenen Thread läuft, Botschaften in eine Input Queue gestellt bekommt, und im Falle von Vererbung die Botschaften, mit denen es nichts anfangen kann, analog zu den JS Prototypen an die nächsthöhere Instanz weiterschickt. Auch Properties werden über Messaging ausgelesen. Keine Ahnung, ob schon mal jemand sowas gebaut hat.

                      Auf einer etwas höheren Ebene läuft das CTI System von Genesys, das meine Firma einsetzt, so ab. Die Objekte sind eine Menge Dienste, die relativ feingranular aufgeteilt sind und auf einem oder 100 Servern laufen können, und die schicken sich über ein genormtes API eine MASSE an Botschaften via TCP. Wer das API kennt, kann mitfunken. Mach ich fleißig 😀

                      Rolf

                      --
                      sumpsi - posui - clusi
                      1. Hallo Rolf,

                        die Methode wäre die Nachricht, die man an das Objekt schickt.

                        Äh, nein. Zumindest habe ich das in Smalltalk anders gelernt.

                        Smalltalk habe ich nie gelernt, dafür bin ich zu jung (Jahrgang '82). Aber unser Dozent hat uns das so erklärt. Methoden sind die Implementation von Nachrichten, die man an Objekte sendet. Aber nagel mich da nicht drauf fest, verifiziert habe ich das jetzt nicht.

                        Eine OOP Sprache mit echtem Messaging, das stelle ich mir so vor, dass jedes Objekt in einem eigenen Thread läuft, Botschaften in eine Input Queue gestellt bekommt, […]

                        Du beschreibst bis hierher das Actor-Modell von Erlang 😝 nur dass es hier nicht Objekt heisst (Erlang ist eine funktionale Sprache), sondern Prozess.

                        und im Falle von Vererbung die Botschaften, mit denen es nichts anfangen kann, analog zu den JS Prototypen an die nächsthöhere Instanz weiterschickt. Auch Properties werden über Messaging ausgelesen. Keine Ahnung, ob schon mal jemand sowas gebaut hat.

                        Mir als language nerd ist zumindest keine Sprache bekannt, dass message passing so… ursprünglich umsetzt.

                        Freundliche Grüße,
                        Christian Kruse

                        1. Du beschreibst bis hierher das Actor-Modell von Erlang 😝 nur dass es hier nicht Objekt heisst (Erlang ist eine funktionale Sprache), sondern Prozess.

                          Ich bin gerade zufällig über ein Interview mit Joe Armstrong, einem der Designer von Erlang, gestolpert, da sagt er den bemerkenswerten Satz:

                          […] Erlang might be the only object oriented language […]

                          Und Alan Kay, Designer von Smalltalk und Namensgeber von OOP, sagt dazu:

                          And, he might be right. Erlang is much closer to the original ideas I had about “objects” and how to use them.

                      2. Eine OOP Sprache mit echtem Messaging, das stelle ich mir so vor, dass jedes Objekt in einem eigenen Thread läuft, Botschaften in eine Input Queue gestellt bekommt […]. Auch Properties werden über Messaging ausgelesen. Keine Ahnung, ob schon mal jemand sowas gebaut hat.

                        Kennst du das Actor Model? Erlang und Elixir sind zwei prominente Vertreter davon, auch wenn sie eher als funktional denn als objektorientiert klassifiziert werden.

                        Ich selber arbeite gerade übrigens an MontiArc, das ist eine Programmiersprache für verteilte Systeme. System-Designer*innen erstellen damit Modelle und Spezeifikation und im Hintergrund wird automatisch überprüft, ob das Modell die Spezifikation erfüllt. Unser Concurrency-Modell ist dem Actor Model auch sehr ähnlich.

                        1. Hallo 1unitedpower,

                          Kennst du das Actor Model?

                          Hihi.

                          Erlang und Elixier sind zwei Prominente Vertreter davon, auch wenn sie eher als funktional denn als objektorientiert klassifiziert werden.

                          Das Forum ist übrigens in Elixir geschrieben.

                          Freundliche Grüße,
                          Christian Kruse

                          1. Kennst du das Actor Model?

                            Hihi.

                            Da war ich zu langsam.

                            Erlang und Elixier sind zwei Prominente Vertreter davon, auch wenn sie eher als funktional denn als objektorientiert klassifiziert werden.

                            Das Forum ist übrigens in Elixir geschrieben.

                            Ich weiß, ich finds beeindruckend, dass du inzwischen die Forensoftware einmal in einer rein prozeduralen Programmiersprache, in einer OOP Sprache und einer funktionalen Sprache geschrieben hast. BTW: Du hättest die Ruby-Version rforum, und die Elixir-Version eforum nennen sollen 🐶

                            1. Hallo 1unitedpower,

                              Ich weiß, ich finds beeindruckend, dass du inzwischen die Forensoftware einmal in einer rein prozeduralen Programmiersprache, in einer OOP Sprache und einer funktionalen Sprache geschrieben hast.

                              Manche finden es beeindruckend, andere traurig 😂 das Forum ist halt ein Hobby. Es muss mir Spaß machen. Die Implementation in C war der Notwendigkeit geschuldet (damals hatten wir halt keine Hardware), die Implementation in Ruby war Pragmatismus (in Rails kann man halt verdammt schnell entwickeln) und die Implementation in Elixir basiert wieder auf Fandom. Ich mag Elixir wirklich.

                              BTW: Du hättest die Ruby-Version rforum, und die Elixir-Version eforum nennen sollen 🐶

                              Das höre bzw. lese ich nicht zum ersten mal 😉

                              Freundliche Grüße,
                              Christian Kruse

                  2. Denn die Idee von OOP ist ja eigentlich, dass man einen Schwarm von Objekten hat, die sich gegenseitig Botschaften schicken.

                    Ganz bestimmt nicht. Aber ich kenne Einige die so programmieren. MFG

                    1. Hallo pl,

                      Denn die Idee von OOP ist ja eigentlich, dass man einen Schwarm von Objekten hat, die sich gegenseitig Botschaften schicken.

                      Ganz bestimmt nicht.

                      Doch. Genau aus dieser Idee ist modernes OOP entstanden. 1UP hat es gut zusammengefasst.

                      Freundliche Grüße,
                      Christian Kruse

                    2. Denn die Idee von OOP ist ja eigentlich, dass man einen Schwarm von Objekten hat, die sich gegenseitig Botschaften schicken.

                      Ganz bestimmt nicht. Aber ich kenne Einige die so programmieren. MFG

                      Auch in Perl treiben manche solche Blüten; ein Objekt für Header (1), eins für Cookies (2), eins für den Body (3). Und diese 3 Objekte werden dann dem Konstruktor für den Useragent übergeben der dann die Requesmethode aufruft. GGf. wird noch ein 4. Objekt für die Parameter benötigt.

                      Aber dem nicht genug, auch die Response liefert wieder mehrere Objekte; eins für die Header, eins für die Cookies und ein Objekt was eine Methode kennt um an den Body zu kommen.

                      Und hier im Forum wurde kürzlich gepostet wie man Objekte für thead, row, cell, tbody usw. erstellt und diese dann dem Konstruktor übergibt der eine Tabelle damit erstellen soll.

                      Das ist OOP zum Selbstzweck und fern jeglicher Praxis.

                      Schönen Sonntag.

                      1. Hallo pl,

                        Und hier im Forum wurde kürzlich gepostet wie man Objekte für thead, row, cell, tbody usw. erstellt und diese dann dem Konstruktor übergibt der eine Tabelle damit erstellen soll.

                        Im Rahmen einer Frage.

                        Bis demnächst
                        Matthias

                        --
                        Du kannst das Projekt SELFHTML unterstützen,
                        indem du bei Amazon-Einkäufen Amazon smile (Was ist das?) nutzt.
              2. Mir geht das auch gegen den Strich. Aber ehe ich das bei jedem meiner Posts erklären muss, verwende ich lieber gleich den Begriff Methode. So hat halt jeder seine Methoden. MFG

              3. an dieser Stelle muss ich mal ketzerisch (oder naiv?) fragen, warum man in der OOP Funktionen einer Klasse nicht mehr Funktionen nennt, sondern Methoden.

                Der Begriff "Objektorientierte Programmierung" wurde in den 70ern das erste mal von Alan Kay verwendet als er mit der Entwicklung von Smalltalk beschäftigt war. In den frühen Veröffentlichungen ist auch schon von Methoden die Rede. Simula ist noch älter als Smalltalk und gilt nach heutigem Maßstab als erste objektorientierte Programmiersprache, aber die Nomenklatur wurde eben von Smalltalk geprägt. C++ und Java sind erst Jahre nach Smalltalk erschienen. Diese Sprachen wurden auch als OOP Sprachen beworben, hatten aber mit Smalltalk und Simula nicht mehr viel zu tun. Alan Kay hat ürbigens mal gesagt, dass er die Wortwahl "objektorientiert" von damals bereut, weil der eigentliche Fokus für ihn auf "message passing" lag und nicht auf "Objekten".

              4. warum man in der OOP Funktionen einer Klasse nicht mehr Funktionen nennt, sondern Methoden

                Der wesentliche Unterschied zur Funktion ist, daß beim Aufruf einer PHP Methode implizit die Instanz übergeben wird. So hat man innerhalb einer Methode Zugriff auf die Eigenschaften der Instanz und kann mit der Instanz weitere Methoden aufrufen.

                In PHP ist dieser Sachverhalt durch die vordefinierte Variable $this hardcodiert. In Perl hingegen erfolgt die Übergabe explizit, d.h. entweder über den Pfeiloperator oder die Argumentenliste. Der Aufruf kann also so oder so erfolgen;

                $f->foo();
                foo($f);
                

                Und innerhab einer Perl Methode kann man die Instanz benennen wie man will, gewöhnlich wird sie da $self genannt oder auch $this und muss als Solche stets aus der Argumentenliste extrahiert werden

                sub foo{
                  my $self = shift;
                }
                

                Um die Verwirrung komplett zu machen; beim Aufruf einer Klassenmethode die auch statische Methoden genannt werden, wird nicht die Instanz übergeben sondern der Name der Klasse. In Perl;

                $f = Foo->new();
                

                ist der Konstruktor also eine statische Methode welche die Instanz liefert und heißt gewühnlich new() wobei man diese Funktion auch anders nennen kann.

                In PHP hingegen wird zwischen new und Konstruktor unterschieden. Noch verwirrender in PHP ist, Eigenschaften der Instanz klassenweit zu deklarieren obwohl noch gar keine Instanz existiert. Man kann aber auch in PHP die Eigenschaften innerhalb des Konstruktors vergeben, so sieht man auch daß die zur Instanz gehören und nicht zur Klasse.

                MFG

                1. Hallo pl,

                  deine Kritik läuft darauf hinaus, dass OOP in Perl hemdsärmelig dazugestrickt sehr offen gestaltet ist, während PHP es systematischer angeht.

                  Eine Klassendeklaration ist ein Stempel, mit dem Du beliebig viele Objekte erzeugen kannst. Das Protokoll, wie die Objektreferenz den Methoden bekannt gegeben wird, ist festgelegt.

                  Eine Klassendeklaration in Perl gibt's überhaupt nicht, du segnest einfach ein Objekt mit einem Package und die Funktionen darin sind dann die Methoden. Darum kann man das schlecht vergleichen. Ob ich nun $this vorgekaut bekomme oder es mir explizit herausshifte, ist vermutlich bis auf ein paar Nanosekunden egal. Aber ich muss in die Methode schauen und gucken ob sie sich ein $self herausholt, um zu wissen, ob sie statisch ist oder nicht.

                  Die Deklaration von Eigenschaften und Methoden in einer Klassendeklaration hat den zwei Zwecke.

                  1. Man sieht deutlich an der Deklaration, was die Klasse enthält und wie es verwendet wird (statisch/Instanz, private/protected/public). In Perl muss ich das Package inspizieren und den Konstruktor finden und verstehen, um das zu wissen.

                  2. Ich kann Datenkapselung betreiben, indem ich bestimmte Eigenschaften oder Methoden als private oder protected deklariere, so dass sie nur innerhalb der Klasse verfügbar sind. Dadurch verhindere ich, dass Unbefugte den Zustand meines Objekts verändern (ja, ich weiß, die FP-Vertreter wenden jetzt ein, dass ein veränderlicher Objektzustand ohnehin die Quelle der meisten Übel ist). Ob man in Perl überhaupt private Eigenschaften kennt, habe ich nicht herausgefunden.

                  In PHP hingegen wird zwischen new und Konstruktor unterschieden

                  PHP erledigt einiges der Instanz-Erzeugung eigenständig (Speicher für Eigenschaften allocieren, Objekt mit der Klasse segnen), darum gibt's einen new-Operator der das auslöst. Der Konstruktor muss dann von PHP selbst gefunden werden können, damit man ihn nicht bei jedem new Foo() explizit angeben muss.

                  Noch verwirrender in PHP ist, Eigenschaften der Instanz klassenweit zu deklarieren obwohl noch gar keine Instanz existiert.

                  Es ist eine Deklaration, mehr nicht. Sie dient - wie oben geschrieben - als Stempel für den Moment, wo die Klasse instanziiert wird. Dass Du undeklarierte Eigenschaften dynamisch hinzufügen kannst, führt aus meiner Sicht zu schwer verständlichem Code. Ab PHP 7.4 wird das weiter verbessert, da geht (optional) dies:

                  class Foo {
                     private int $i;
                     public function __construct() {
                        $this->i = 47;
                        $this->i = "Hugo";    // Fatal error:  Uncaught TypeError
                     }
                  }
                  

                  Ohne deklarierte Eigenschaften hättest Du diese Möglichkeit nicht. Ich bin ein Fan von statisch getypten Sprachen, die ersparen viel Kopfschmerz.

                  Übrigens, für Perl-Nostalgie in PHP kannst Du sowas programmieren (solltest Du aber nicht, jede Sprache hat ihre Idiome und man sollte sie nicht transplantieren):

                  class Foo {
                     static function new() {
                        return new Foo();
                     }
                     function __construct() {
                        // do sth
                     }
                  }
                  
                  $f = Foo::new();
                  

                  Und eine reservierte Funktion In PHP 5 kannst Du den Konstruktor einer Klasse Foo noch Foo() nennen, ab 7 ist das deprecated und es gibt nur noch __construct.

                  Das soll jetzt keine Wertung darstellen. PHP gibt Dir die Möglichkeit, mehr zu erzwingen. Perl lässt Dir viel mehr Freiheiten. Aus meiner Sicht sind das Freiheiten, die das Verständnis des Programms erschweren können. Aber das bin nur ich.

                  Rolf

                  --
                  sumpsi - posui - clusi
                  1. Aus meiner Sicht sind das Freiheiten, die das Verständnis des Programms erschweren können. Aber das bin nur ich.

                    Du sagst es; sie können. Ob ein Programm verständlich ist oder nicht, hängt jedoch von einer Reihe gänzlich anderer Faktoren ab die mit der Programmiersprache gar nichts zu tun haben.

                    MFG

                  2. problematische Seite

                    Eine Klassendeklaration in Perl gibt's überhaupt nicht, du segnest einfach ein Objekt mit einem Package und die Funktionen darin sind dann die Methoden.

                    Kann man machen. Macht aber keiner. Vielmehr tut auch ein Perlentwickler seine Klasse sauber deklarieren;

                    package Egal{
                      sub new{
                         my $class = shift;
                         bless{
                            NUM => 123,
                            # weitere Eigenschaften
                         }, $class;
                      }
                    };
                    

                    und siehe, da man, im Gegensatz zu PHP, praktisch gezwungen ist einen Konstruktor zu schreiben, wird man genau da auch sämtliche Attribute deklarieren. Dasselbe macht man in PHP eben außerhalb des Konstruktors weil eine Deklaration Letzteren nicht zwingend notwendig ist.

                    Was in PHP (noch) fehlt ist POD, Beispiel s.o.

                    POD steht für Plain Old Document, mit perdoc File wird sie für obenstehende Package abgerufen. Und wer will kann auch mit pod2html die in der Klasse eingebettete Dokumentation als HTML erzeugen.

                    MFG

  3. Hallo pl,

    das hier versteht PHP nicht (mailer.inc enthält nur die function sendMail):

    class Dings {
       require "mailer.inc";
       
       public function MailIt() {
          $this->sendMail();
       }
    }
    

    Aber du kannst mit anonymen Funktionen (ab 5.3 vorhanden) etwas machen:

    Datei mailer.inc

    <?php
    return function() {
       echo "I can send a mail\n";
    }
    

    und die Verwendung:

    class Foo {
       public function DoMail() {
          $sendMail = include "mailer.inc";
          $sendMail();
       }
    // oder so
       public function MooMail() {
          $this->sendMail = include "mailer.inc";
          ($this->sendMail)();
       }
    }
    

    In MooMail sind die Klammern wichtig, sonst sucht er eine Methode sendMail, findet das Property und moppert. PHP ist nicht JavaScript.

    Dann ist die anonyme Funktion, die mailer.inc zurückgibt, nur im Kontext der DoMail Methode oder der Foo-Klasse vorhanden.

    Aber ich würde das nicht tun. Im Sinne von SoC gehört der Mailer mit sehr hoher Wahrscheinlichkeit in eine eigene Klasse. Damit es keine Namenskollisionen gibt, legen wir auch noch einen Namespace drumherum (ebenfalls ab PHP 5.3):

    mailer.inc

    <?php
    namespace rost\mail;
    
    class Mailer {
       public function send() {
          echo "I can send a mail\n";
       }
    }
    

    und die Verwendung:

    class Foo {
       public function DoMail() {
          require_once "mailer.inc"; 
          $mailer = new \rost\mail\Mailer();
          $mailer->send();
       }
    }
    

    Die Mailer-Klasse ist dann auch außerhalb der Foo Klasse verfügbar, Klassendefinitionen sind immer global. Aber das schadet vermutlich nichts.

    Rolf

    --
    sumpsi - posui - clusi
    1. Die Mailer-Klasse ist dann auch außerhalb der Foo Klasse verfügbar,

      So verstehen wir uns miss. Wenn Foo meine Klasse ist, gehts mir nur darum eine Foo-Instanz um die Mailfunktion zu erweitern.

      Wobei die Mailfunktion in eine Datei ausgelagert gehört, damit sie auch von Instanzen anderer Klassen genutzt werden kann, nach demselben Mechanismus.

      # in einer beliebigen Methode einer beliebigen Klasse
      # haben wir die Instanz in $this
      # und das soll möglich sein: 
      require_once "Mail.php";
      $this->mail();
      

      Mir ist klar, daß hier der Namespace erweitert werden muss. Aber was muss in Mail.php drinstehen? Wenn ich da function mail(){} zu stehen habe, wird diese Funktion in den globalen Namespace geladen. Sie soll jedoch zum Namespace derjenigen Klasse gehören die für Foo die Basisklasse ist.

      MFG

      Klassenhierarchie

      class main{}
      class Foo extends main{}
      
      $foo = new Foo;
      require_once "Mail.php";
      $foo->mail();
      
      1. Hallo pl,

        gehts mir nur darum...

        Lass es mich anders formulieren: ICH WILL ABER. Ja gut. Kann ich ja verstehen. Man macht sich einen Plan und hört dann nicht gerne, dass das keine gute Idee ist.

        Habe gerade noch die runkit-Erweiterung gefunden (findest Du im PHP Handbuch), aber ich würde das nicht tun. Diese Erweiterung scheint auch nicht unbedingt gut mit PHP 7 zu funktionieren.

        Mit einem einfachen include ist es aber trotzdem nicht getan. Das ist im Konzept von PHP so nicht vorgesehen. Mal eben eine Methode an ein Objekt - oder schlimmer noch, an eine Klasse - zu schrauben, ist eine gefährliche Sache. Das Laufzeitverhalten kann dadurch völlig unvorhersehbar werden, vor allem wenn Vererbung ins Spiel kommt.

        Was Du da haben willst, ist selbstmodifizierender Code, und das ist einer der brisantesten Footguns, seit Johnny Neumann Code und Daten in einen Speicher legte.

        Siehst Du denn einen gravierenden Vorteil darin, den Mailer als Methode an die aktuelle Klasse zu schrauben, statt einfach ein Objekt einer Workerklasse zu erzeugen? Ich sehe es eher als nachteilig. Das Anschrauben der Methode bedeutet, diese Methode nachher in mehreren Klassen des Systems herumfliegen zu haben.

        Wobei die Mailfunktion in eine Datei ausgelagert gehört, damit sie auch von Instanzen anderer Klassen genutzt werden kann

        Genau das ist das Signalwort für: Eigene Klasse!

        Den Worker mit require_once zu holen bedeutet, die Implementierung genau einmal zu laden und dann nur noch von überall, wo sie gebraucht wird, zu verwenden. Es ist nur eine Codezeile mehr: $mailer = new Mailer();

        Wenn es deine Absicht ist, dass der Mailer Methoden oder Eigenschaften der Klasse nutzt, in die er hinein geladen wird, dann warne ich erneut. Auch das führt in den OOS[1]-Abgrund. Wenn der Mailer Daten braucht, musst Du ihn damit versorgen. Er sollte sie sich nicht implizit selbst holen.

        Eine halbwegs transparente Version des "selbst holens" kannst du mit Interfaces erreichen. Der Mailer bekommt beim new ein Objekt übergeben, das ein bestimmtes Interface implementiert. Über dieses Interface kann der Mailer seine Daten abrufen, und er kann mit $dataprovider instanceof IMailerDataProvider auch sicherstellen, dass in $dataprovider eine Implementierung dieses Interfaces geliefert wird.

        Wenn Du einfach eine Methode mail bereitstellen musst, weil ein anderes Codestück das erwartet und du die Funktionsprinzipiien deines Perl-Frameworks möglichst unverändert abbilden willst, dann könntest Du die Methode in einer Basisklasse bereitstellen. Die Implementierung kann trotzdem in der Mailerklasse liegen: das bereitgestellte mail() ist lediglich ein Durchlauferhitzer, holt den Mailer mit require_once herein, instanziiert ihn und ruft ihn auf.

        Rolf

        --
        sumpsi - posui - clusi

        1. Objekt-Orientiertes Spaghetti ↩︎

        1. In Perl führt da gar nichts in den Abgrund, ganz im Gegenteil: Code wir durch Teilung effizienter. Warum auch soll man einen Haufen Methoden kompilieren wenn man bestimmte Methoden davon nur gelegentlich braucht!?

          Genauso kann man das natürlich auch mit Klassen machen und selbstverständlich auch mit PHP Klassen. Meine FW Interfaces hab ich übrigens sowohl in Perl als auch in PHP so implementiert wie Du das beschrieben hast.

          MFG

          1. Hallo pl,

            you didn‘t get it.

            Freundliche Grüße,
            Christian Kruse

          2. In Perl führt da gar nichts in den Abgrund, ganz im Gegenteil: Code wir durch Teilung effizienter. Warum auch soll man einen Haufen Methoden kompilieren wenn man bestimmte Methoden davon nur gelegentlich braucht!?

            Genauso kann man das natürlich auch mit Klassen machen

            D.h., man kann nicht nur sondern macht es zweckmäßigerweise auch so daß Klassen und -erweiterungen die Aufgabe spezialisieren.

            In Perl ist es z.B. möglich, Klassen zu definieren wo sämtliche Methoden aus .so Dateien (XS) oder aus dem FS (Autoload) geladen werden. Zum Vermeiden von Coderedundanzen und zum Aufbau einer Factory ist sowas natürlich eine feine Sache.

            Methoden einer Factory werden ja gerade deswegen ins FS ausgelagert wenn sie selber weiteren Code mit require einbinden der zum Ausführen einer Methode benötigt wird, bei der Instanzerstellung jedoch noch gar nicht verfügbar ist (i.e. Late Delegation).

            MFG

  4. PS; Die Frage, wie man Instanzen um Methoden erweitert wo zum Zeitpunkt der Instanzerstellung noch gar nicht feststeht welche das sind und ob sie überhaupt gebraucht werden ist eine der Kernfragen praktischer OOP.

    Schönen Sonntag.

    1. Hallo pl,

      um deiner Zusammenfassung des Threads meine Zusammenfassung hinzuzufügen:

      Es ist das älteste Technologiethema von allen. "Wie" vs "Ob".

      Rolf

      --
      sumpsi - posui - clusi
      1. Oder anders ausgedrückt: Das Organisieren von Code in Methoden ist nur die Fortsetzung des Organisieren von Code in Klassen.

        MFG

        1. Dieser Beitrag wurde gelöscht: Der Beitrag ist unkonstruktiv oder provokativ und trägt zu einer Verschlechterung der Stimmung bei.
      2. Dieser Beitrag wurde gelöscht: Beitrag ist Spam.