Magische Methode für Zuweisung?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • #16
    Zitat von fireweasel Beitrag anzeigen
    Ganz sicher? Von welchem Java-Clone redest du?
    Ich habe nicht gesagt, dass Java das Überladen von (Zuweisungs)operatoren unterstützt. Aber es weist in diesem Fall genau das Verhalten auf, welches ich in PHP (falls möglich über eine magische Methode) simulieren wollte.

    Ob es noch das selbe oder ein neues Objekt ist spielt für meinen Zweck keine Rolle. Wichtig ist nur, dass es ein Objekt bleibt. Da genau das aber standardmässig in PHP aufgrund der fehlenden Typisierung nicht möglich ist, dachte ich an die Option der magischen Methoden.

    Für mein Experiment werde ich einfach weiterhin $obj.set($v); oder $obj($v); statt $obj=$v; nutzen

    Kommentar


    • #17
      Zitat von sili Beitrag anzeigen
      Ich habe nicht gesagt, dass Java das Überladen von (Zuweisungs)operatoren unterstützt. ...
      Ja, das hab ich auch zwischenzeitlich bemerkt.
      Mit diesem überladbaren Zuweisungsoperator steht und fällt aber dein Interpretationsversuch deines Quellcodebeispiels. Ohne macht es nicht, was du denkst, das es täte ...

      ... Aber es weist in diesem Fall genau das Verhalten auf, welches ich in PHP (falls möglich über eine magische Methode) simulieren wollte.
      Nee, nee, nee -- tut es eben nicht.

      Ob es noch das selbe oder ein neues Objekt ist spielt für meinen Zweck keine Rolle. Wichtig ist nur, dass es ein Objekt bleibt.
      Mal ernsthaft: Was sollte es für einen Sinn ergeben, zuerst einer Variablen einen Wert zuzuweisen, nur um ihr danach einen typgleichen aber anderen Wert zuzuweisen, damit man anschließend so tun kann, als rufe man die Methoden des ersten zugewiesenen Wertes auf?

      Da genau das aber standardmässig in PHP aufgrund der fehlenden Typisierung nicht möglich ist, ...
      Doch ist es. Mit der Typisierung hat das nichts zu tun. PHP ist typisiert (was auch immer du darunter verstehen magst) ...

      PHP-Code:
      // etwas Vorbereitung:

      class Bar {
          function do() {}
      }

      class 
      Foo extends Bar {
      }

      // Dein Beispiel:

      $v = new Foo();

      // $v = 'bar';
      $v = new Bar('bar');

      $v->do(); 
      Das funktioniert, aber der praktische Nutzen erschließt sich mir um diese Uhrzeit nicht ...
      Erleuchte mich.

      Für mein Experiment werde ich einfach weiterhin $obj.set($v); oder $obj($v); statt $obj=$v; nutzen
      Suchst du etwa alternative Konstruktor-Funktionen?

      $obj.set($v) dürfte einen Fehler geben (PHP benutzt "->" zum Ansprechen von Objekt-Eigenschaften. "." ist der Stringverkettungsoperator.

      $obj($v) funktioniert seit einiger Zeit, wenn das Objekt die magische Methode __invoke() besitzt. Das ist ein Nebeneffekt der Einführung von Closure-Objekten.
      Zuletzt geändert von fireweasel; 18.04.2011, 21:49.
      Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

      Kommentar


      • #18
        Ich glaube, ich muss mein Vorhaben etwas erläutern
        PHP5 unterstützt Type Hinting bei den Methodenparameter für Objekte und Arrays, jedoch nicht für primitive Datentypen. Diese Einschränkung würde ich gerne mithilfe einiger Wrapper-Klassen umgehen um so etwas machen zu können:
        PHP-Code:
        class {
            public function 
        b(Integer $x)
            {
                ...
            }

        Dafür suche ich Wege um den Umgang mit den Wrapper-Klassen bzw. dessen Objekten möglichst zu vereinfachen. Bei der Ausgabe lässt sich in einigen Fällen mit __toString() nutzen (zumindest wenn ein String benötigt wird), ansonsten gibt es eine get() Methode. Um einen Wert neu zu setzen wird set() verwendet und genau diesen Teil wollte ich nach Möglichkeit vereinfachen.

        Aber wie gesagt: Über den Sinn oder Unsinn solcher Wrapper-Klassen müsst ihr euch im Übrigen keine Gedanken machen. Es geht nur um ein Experiment um den Umgang mit den primitiven Datentypen zu vereinfachen
        Zuletzt geändert von sili; 18.04.2011, 22:14.

        Kommentar


        • #19
          Zitat von sili Beitrag anzeigen
          Ich glaube, ich muss mein Vorhaben etwas erläutern
          PHP5 unterstützt Type Hinting bei den Methodenparameter für Objekte und Arrays, jedoch nicht für primitive Datentypen. Diese Einschränkung würde ich gerne mithilfe einiger Wrapper-Klassen umgehen ...
          [ ] Du hast schonmal was von den SPL-Wrapper-Klassen für die "primitiven" Datentypen in PHP gehört.
          Zuletzt geändert von fireweasel; 18.04.2011, 22:33.
          Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

          Kommentar


          • #20
            Zitat von fireweasel Beitrag anzeigen
            [ ] Du hast schonmal was von den SPL-Wrapper-Klassen für die "primitiven" Datentypen in PHP gehört.
            Ja hab ich. Dabei handelt es sich aber um eine experimentelle, mehr als drei Jahre alte PECL-Erweiterung mit sehr eingeschränkter Funktionalität. Der Vorteil davon ist jedoch, dass genau die Anfangsfrage damit geklärt werden würde. Trotzdem mache ich das lieber von Hand: Die paar Klassen sind schnell selbst geschrieben und mit dem Nachteil der fehlenden Möglichkeit der direkten Wertzuweisung kann ich leben. Zusätzlich kann ich die "Bibliothek" (wenn man das so nennen kann) einfacher verteilen, da keine zusätzlichen Erweiterungen installiert werden müssen.

            Kommentar


            • #21
              Zitat von sili
              Aber wie gesagt: Über den Sinn oder Unsinn solcher Wrapper-Klassen müsst ihr euch im Übrigen keine Gedanken machen. Es geht nur um ein Experiment um den Umgang mit den primitiven Datentypen zu vereinfachen
              Du kannst dich darauf einstellen, dann Wrapper für sämtliche Standardfunktionen von PHP schreiben und auf Standardoperatoren verzichten zu müssen.

              PHP-Code:
              <?php

              class Integer
              {
                  protected 
              $value;

                  
              /**
                   *
                   * @param int $n
                   */
                  
              public function __construct($n)
                  {
                      
              $this->value = (int) $n;
                  }

                  public function 
              __toString()
                  {
                      return 
              $this->value;
                  }
              }

              class 
              String
              {
                  protected 
              $value;

                  
              /**
                   *
                   * @param string $n
                   */
                  
              public function __construct($s)
                  {
                      
              $this->value = (string) $s;
                  }

                  public function 
              __toString()
                  {
                      return 
              $this->value;
                  }
              }

              $s = new String('Hallo Welt');
              $n = new Integer(6);
              $m = new Integer(9);

              var_dump(substr($s$n));
                  
              // Warning: substr() expects parameter 2 to be long, object given

              var_dump($n $m);
                  
              // int(2)

              echo $n;
                  
              // Catchable fatal error: Method Integer::__toString() must return a string
                  // value
              Die Alternative wäre höchstens, Methoden wie Integer::toInt() zu implementieren und einzusetzen, was irgendwie albern ist.

              Was den aktuellen Stand der PHP-Entwicklung anbelangt, arbeitest du mit dem Ansatz einfach völlig gegen die Sprache. Da gibt es wenig dran zu rütteln.

              Zitat von wahsaga
              Oder kurzum bzw. anders formuliert: Du möchtest eigentlich lieber in einer anderen Sprache als PHP programmieren
              PHP ist nunmal nicht Java.

              PHP-Code:
              class Foo
              {
                  
              /**
                   *
                   * @param int    $int
                   * @param float  $float
                   * @param string $string
                   */
                  
              public function myMethod($int$float$string)
                  {
                      
              $int    = (int)    $int;
                      
              $float  = (float)  $float;
                      
              $string = (string) $string;

                      
              /* ... */
                  
              }

              Mehr ist an Typsicherheit für Primitive nicht drin.

              Kommentar


              • #22
                PHP-Code:
                class Foo {
                    
                /**
                     *
                     * @param int    $int
                     * @param float  $float
                     * @param string $string
                     */
                    
                public function myMethod($int$float$string) {
                        if (! 
                is_int($int)) {
                            throw new 
                InvalidArgumentException('$int must be integer, got ' gettype($int));
                        }
                        if (! 
                is_float($float)) {
                            throw new 
                InvalidArgumentException('$float must be float, got ' gettype($float));
                        }
                        if (! 
                is_string($string)) {
                            throw new 
                InvalidArgumentException('$string must be string, got ' gettype($string));
                        }
                    }

                Kommentar


                • #23
                  Ja, okay. Das wäre konsequenter.

                  Die Frage ist da dann vielleicht, ob wir in der Schnittstelle der dynamischen Typisierung von PHP Rechnung tragen oder ob wir sagen: „Ne, is' nicht, ich will den korrekten Datentyp.“

                  Ich kann's nicht beantworten.

                  Ein Nachteil meiner Methode ist allerdings, dass sie bei der Übergabe von Objekten einen Fehler oder Notices wirft. Das ist im Zweifel wohl eine Antwort.
                  Zuletzt geändert von mermshaus; 19.04.2011, 15:52.

                  Kommentar


                  • #24
                    mermshaus: Natürlich ist das ganze nicht wirklich ideal und ist nicht im Einklang mit der Variablenhandhabung in PHP. Es macht aber genau die Variablenüberprüfung in den Methoden überflüssig. Um die Standardbefehle nicht auch noch selbst implementieren zu müssen, kann man jeweils als erstes in der Methode einfach wieder eine normale Variable setzen ($x = $x->get(); ).

                    Kommentar


                    • #25
                      pQuery

                      PHP-Code:
                      <?php

                      error_reporting
                      (-1);

                      /**
                       *
                       *
                       * String  -> string
                       * Integer -> int
                       * string  -> String
                       * int     -> Integer
                       * 
                       * @param mixed $v
                       * @return mixed
                       */
                      function __($v)
                      {
                          if (
                      is_object($v)) {
                              if (
                      $v instanceof DataType) {
                                  return 
                      $v->___get();
                              } else {
                                  throw new 
                      Exception();
                              }
                          } else {
                              switch (
                      true) {
                                  case (
                      is_string($v)):
                                      return new 
                      String($v);
                                      break;
                                  case (
                      is_int($v)):
                                      return new 
                      Integer($v);
                                      break;
                                  default:
                                      throw new 
                      Exception();
                                      break;
                              }
                          }
                      }

                      abstract class 
                      DataType
                      {
                          protected 
                      $value;
                          public function 
                      ___get() { return $this->value; }
                          public function  
                      __toString() { return (string) $this->value; }
                      }

                      class 
                      Integer extends DataType
                      {
                          public function 
                      __construct($n) { $this->value = (int) $n; }
                      }

                      class 
                      String extends DataType
                      {
                          public function 
                      __construct($s) { $this->value = (string) $s; }
                      }



                      class 
                      SomeModel
                      {
                          public function 
                      replaceTemplateVars(String $templateString $param1,
                                  
                      String $param2)
                          {
                              
                      $template __(str_replace(
                                      array(
                      '{param1}''{param2}'),
                                      array(
                      __($param1), __($param2)),
                                      
                      __($template)));
                              
                              return 
                      $template;
                          }
                      }



                      $model = new SomeModel();

                      $template __('{param1} {param2}!');

                      $param1 __('Hello');
                      $param2 __('World');

                      $template $model->replaceTemplateVars($template$param1$param2);

                      echo 
                      $template;



                      $m __(5);
                      $n __(6);

                      $o __(__($m) + __($n));

                      echo 
                      $o;

                      Kommentar


                      • #26
                        Einfach nur furchtbar. Ich kann mir nicht vorstellen, dass irgendjemand so arbeiten möchte.

                        Kommentar


                        • #27
                          Zitat von mermshaus Beitrag anzeigen
                          pQuery

                          PHP-Code:
                          <?php

                          function __($v)
                          {
                              
                          // ...
                          }

                          //...


                          $param1 __('Hello');
                          $param2 __('World');

                          // ...
                          $m __(5);
                          $n __(6);

                          $o __(__($m) + __($n));

                          // ...
                          Underscore, a Friend Indeed
                          Use _ and __ as identifiers.
                          Aus How To Write Unmaintainable Code


                          PHP-Code:
                          // ...
                                  
                          switch (true) {
                                      case (
                          is_string($v)):
                                          return new 
                          String($v);
                                          break; 
                          Was issn das? Eine doppelte Fall-Through-Sicherung?
                          Doppelt hält besser, oder wie?

                          PHP-Code:
                                      default:
                                          throw new 
                          Exception();
                                          break;
                                  } 
                          Und nochmal in einer anderen Variante?
                          Falls die Exception wider Erwarten nicht geworfen wird, brechen wir den default-Zweig ab, nach dem nichts mehr kommt?

                          Zitat von sili Beitrag anzeigen
                          mermshaus: ... Es macht aber genau die Variablenüberprüfung in den Methoden überflüssig.
                          Mhmmm, eine "robuste" Funktion prüft die ihr übergebenen Argumente selten nur auf den Typ. Meist werden auch noch irgendwelche Schranken abgefragt. Da dann bspw. ein
                          PHP-Code:
                          is_int($arg) || 
                          davor zu setzen, erscheint mir der einfachere Weg. Gut, manchmal übersieht man das und kein Compiler warnt einen dann. Aber wer das befürchtet, benötigt eben eine statisch typisierte Sprache.
                          Zuletzt geändert von fireweasel; 21.04.2011, 10:10.
                          Klingon function calls do not have “parameters”‒they have “arguments”‒and they always win them!

                          Kommentar


                          • #28
                            OffTopic:
                            Zitat von fireweasel Beitrag anzeigen
                            Was issn das? Eine doppelte Fall-Through-Sicherung?
                            Doppelt hält besser, oder wie?
                            Aber immer doch.

                            Auf php.de wurden wir letzte Tage mit sowas erheitert,
                            Code:
                            SELECT id AS id, [...]

                            I don't believe in rebirth. Actually, I never did in my whole lives.

                            Kommentar


                            • #29
                              Zitat von fireweasel
                              Was issn das? Eine doppelte Fall-Through-Sicherung?
                              Doppelt hält besser, oder wie?
                              Das Hässliche an dem Code sind imo eher die verteilten return-Statements und das redundante Werfen der Exception. Dennoch danke für den Hinweis.

                              Aus How To Write Unmaintainable Code
                              File einen Bug gegen gettext.

                              [color=silver]<spoiler>Es sollte zwar nach dem Lesen des Threads klar sein, aber: Der pQuery-Post war ein Witz.</spoiler>[/color]
                              Zuletzt geändert von mermshaus; 21.04.2011, 13:36.

                              Kommentar


                              • #30
                                Zitat von mermshaus Beitrag anzeigen
                                File einen Bug gegen gettext.
                                Den würd ich sogar voten
                                [COLOR="DarkSlateGray"]Hast du die [COLOR="DarkSlateGray"]Grundlagen zur Fehlersuche[/color] gelesen? Hast du Code-Tags benutzt?
                                Hast du als URL oder Domain-Beispiele example.com, example.net oder example.org benutzt?
                                Super, danke!
                                [/COLOR]

                                Kommentar

                                Lädt...
                                X