Nefunkční next v ArrayHash iterátor

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
Retrox
Člen | 11
+
0
-

Dobrý den,

při kódu viz. příklad se iterátor při volaní funkce next nepřesune na další prvek, ale current stále ukazuje na počáteční a ne další v pořádí.

$pole = new Nette\ArrayHash();
$pole->offsetSet(1,"test01");
$pole->offsetSet(1,"test02");
$pole->getIterrator()->rewind();

while ($pole->getIterator()->valid() === true){
	Debugger::dump($pole->current());
        $pole->next()
}

Předpokládal bych, že kód vypíše test01 a test02 a skončí a ne že vytvoří nekonečnou smyčku. Děkuju

Editoval Retrox (6. 8. 2012 13:58)

Filip Procházka
Moderator | 4668
+
0
-

Víš, že getIterator() vytváří vždy nový objekt?

$pole = new Nette\ArrayHash();
$pole->offsetSet(1,"test01");
$pole->offsetSet(1,"test02");

$iterator = $pole->getIterrator();
$iterator->revind();
while ($iterator->valid() === true){
        dump($iterator->key(), $iterator->current());
        $iterator->next()
}

A doufám, že máš dobrý důvod používat while, protože si myslím, že nemáš, vzhledem tomu, že se neumíš podívat na implementaci metody ArrayHash::getIterator().

$pole = new Nette\ArrayHash();
$pole->offsetSet(1,"test01");
$pole->offsetSet(1,"test02");
foreach ($pole as $key => $value) {
	dump($key, $value);
}

Editoval HosipLan (6. 8. 2012 15:19)

Retrox
Člen | 11
+
0
-

Podívat se do Dokumentace jak to řeší David mě nenapadlo. Moje chyba. Vím že to sem nebude patřit, ale můžes mi pak vysvětlit výhodu vytvoření nového objektu než práci se stávajícím. Dík

Filip Procházka
Moderator | 4668
+
0
-

Myslím že to nedokážu. Zkusím ti to ale shrnout do tří písmenek: OOP.

Yrwein
Člen | 45
+
0
-

Retrox: Kdyby se nevytvářel vždy nový objekt, vedlo by to při vnořeném procházení téhož objektu k nemilým překvapením (konkrétně by se po ukončení prvního vnořeného cyklu ukončil i ten, který ho vytvořil). (Edit: Samozřejmě s předpokladem, že se iteruje pomocí foreache.)

U rozhraní IteratorAggregate je vracení nové instance běžná praxe, viz. ukázková implementace (samotný popis rozhraní se k tomuhle nevyjadřuje nejjasněji).

Editoval Yrwein (6. 8. 2012 17:22)

Šaman
Člen | 2632
+
0
-

Rohodně je to offtopic, ale ten odkaz na OOP nechápu. Mám-li v objektu getter, tak předpokládám, že mi bude vracet stále stejnou členskou proměnnou, v tomto případě Iterator. Pro stávající chování by se mi víc líbil název createIterator().
V souvislosti s Nette a jeko prapředkem Objectem pak totiž hrozí i zápis

$iterator = $myArrayHash->iterator;

a u toho je vytváření nového objektu skoro WTF. Takže odkazem na OOP bych neargumentoval.

Edit: Díky Yrwein, to už dává smysl.

Editoval Šaman (6. 8. 2012 17:28)

redhead
Člen | 1313
+
0
-

@Šaman: To určitě. Holt to ale vývojáři PHP pojmenovali takto, tak s tím musíme žít. V Javě je to dokonce zkráceno na pouhý iterator().

Jinak důvod podle mě vychází už z C/C++ – kdyby více vláken operovalo nad stejným objektem iterátoru, bylo by velmi, velmi zle.

Editoval redhead (6. 8. 2012 17:36)

redhead
Člen | 1313
+
0
-

Ou a dokumentace se k tomu sice nevyjadřuje nejlépe (asi by to chtělo více detailněji), ale přeci jen:

Interface to create an external Iterator.

Všimněte si dvou důležitých slov – create a external.

Filip Procházka
Moderator | 4668
+
0
-

Šaman napsal(a):

Rohodně je to offtopic, ale ten odkaz na OOP nechápu. Mám-li v objektu getter, tak předpokládám, že mi bude vracet stále stejnou členskou proměnnou, v tomto případě Iterator. Pro stávající chování by se mi víc líbil název createIterator().

Máš naprostou pravdu. Vysvětli to vývojářům PHP :)