Keine Sprachkonstrukte für IteratorAggregate?

Hallo!

Ich habe gestern (wieder) angefangen, mir ein paar (nie da gewesene und längst vergessene) PHP5-kenntnisse anzueignen, hab erstmal eine einfach verkettete Liste geschrieben, diese funktioniert auch, wo ich aber nicht vorankomme: wie mache ich so etwas zu einem IterableAggregate? Wohin mit der Iterator-Klasse? Instanzen der Iterator Klasse müssen ja irgendwie auf die “Innereien” der LinkedList-Klasse zugreifen (etwa auf “head” beim rewind).

  • nested classes gibt es nicht, ansonsten könnte man Iterator als geschachtelte Klasse in LinkedList implementieren

  • anonyme inner classes (wäre mein instrument der wahl in java gewesen) gibt es nicht

  • “package-sichtbarkeit” oder “datei-sichtbarkeit” gibt es nicht (ansonsten könnte ich die “innereien” datei-sichtbar deklarieren, und mich damit begnügen)

  • so etwas wie friend-klassen aus C++ gibt es anscheinend auch nicht

  • einfach alles public deklarieren? Wozu der Zirkus dann überhaupt?

mir sind leider irgendwie die ideen ausgegangen, ich wüsste nicht mal, wonach ich googlen soll?

Hab mal in der Implementierung von SplDoublyLinkedList nachgeschaut: es implementiert nur Iterator[nix Aggregate!]?

Heißt es dann, dass man über eine Liste mit zwei Iteratoren gleichzeitig nicht mal lesend laufen kann?

Danke im Voraus.

PS: hab eben rausgefunden, dass PHP auch keine Threads unterstützt… omg^^ ó_Ò?

Also das Interface IteratorAggregate ist erstmal dazu da einem Typen die Fähigkeit zu verleihen das man diesen iterieren kann, d.h. es ermöglicht das man ein Objekt dieses Typs wie ein Array in foreach verwenden kann. Dabei spielt es noch keine Rolle welcher Typ von Iterator diesen Typ unterstützt.

Jetzt kommen wir zum Iterator selbst: Das Interface Iterator kann man implementieren um einen Iterator zu erstellen. Jetzt ist es Deine freie Entscheidung ob Du jetzt eine eigene Klasse als Iterator implementierst. Genauso könntest Du die Klasse die Du iterieren möchtest selbst das Iterator Interface implementieren lassen.

Eine Klasse gegen beide Interfaces zu implementieren wäre redundant und unsinnig. Denn wenn Du bereits das Iterator Interface implementierst brauchs Du nicht noch zusätzlich ein Aggregate dafür.

Bsp:


class MyLinkedListIterator implements Iterator {
  public function __construct(MyLinkedList $list) {
  }
  // implement the iterator stuff ...
}

class MyLinkedList implements IteratorAggregate {
  // implement the linked list stuff ...

  public function getIterator() {
    return new MyLinkedListIterator($this);
  }
}

oder:


class MyLinkedList implements Iterator {
  // implement the linked list AND iterator stuff ...
}

Da Du Dir jetzt noch Gedanken zur Sichtbarkeit der Listelemente gemacht hast wäre es in Deinem Falle am besten das Iterator Interface direkt in Deine Liste zu implementieren, genau so wie es die SPL macht. Wenn nicht wäre es eine Aufgabe für Dich Dir Gedanken zu machen wie Du Deine Listenknoten dem Iterator sichtbar machst (sinnvolle getter/setter etc.).

Gut Schuß
VuuRWerK :wink:

redundant & unsinnig: ja, äquivalent: nein.
IteratorAggregate kann bei jeder getIterator-anfrage einen neuen iterator liefern, insbesondere kann eine datenstruktur von mehreren unabhängigen iteratoren durchlaufen werden.


class MyLinkedListIterator implements Iterator {
  public function __construct(MyLinkedList $list) {
  }
  // implement the iterator stuff ...
}

„implement iterator stuff“ geht imho eben nicht, weil’s mit der sichtbarkeit nicht hinhaut, oder zumindest mal hässlich wird, sodass es rein gar nichts mehr mit sauberem code zu tun hat…

Angesichts der tatsache, dass man mit php eh nicht multithreaden kann, gebe ich mich also mit direkten Implementierung von Iterator (nach Vorbild der SPL) zufrieden: Beispiele, wo man mehrere Iteratoren gleichzeitig braucht, sind eh ein wenig konstruiert… Also, es gibt natürlich ein paar wichtige algorithmen, wo man das gut gebrauchen kann, aber es macht wenig bis gar keinen sinn, diese in php zu implementieren. Daher bin ich auch mit dem wenigen zufrieden, was die Mächtigkeit von PHP so hergibt.

Danke.

Hab ich nie behauptet sondern ich bin nur oberflächlich geblieben um Dich eigentlich nicht noch mehr zu verwirren.

[QUOTE=0x7F800000;11625]
IteratorAggregate kann bei jeder getIterator-anfrage einen neuen iterator liefern, insbesondere kann eine datenstruktur von mehreren unabhängigen iteratoren durchlaufen werden.[/QUOTE]
Richtig, das war aber nicht Deine Frage :wink:

[QUOTE=0x7F800000;11625]
„implement iterator stuff“ geht imho eben nicht, weil’s mit der sichtbarkeit nicht hinhaut, oder zumindest mal hässlich wird, sodass es rein gar nichts mehr mit sauberem code zu tun hat… [/QUOTE]
Auch wenn man das nicht macht doch zitiere ich mich mal fix selbst:

Vor dem Problem stehst Du aber nicht nur bei PHP sondern auch anderen Sprachen. In Java und C# mag es mithilfe der Package-Sichtbarkeit und/oder Inner-Classes gehen aber ob das der Weisheit letzter Schluß ist oder nur eine Krücke? Bei C++ hat man zwar auch wieder Inner-Classes aber bei einem Blick in die STL sieht man das für iteratoren keine Inner-Classes verwendet werden sondern extern implementiert sind, gut in C++ hat man wieder die Möglichkeit der direkten Speichermanipulation (so zum Beispiel der std::vector< T > und dessen iterator Implementierung: chunk (data()), index, length).

Also wie gesagt, Iterator Interface direkt implementieren und damit leben, dass wenn man mit PHP arbeitet an einigen Ecken immernoch dazu gezwungen ist „unsauberen“ Code zu produzieren. Schau Dir die API von PHP an da weißt Du vorher es kommt :stuck_out_tongue_winking_eye:

Gut Schuß
VuuRWerK :wink: