モダンPHP - ちょびっとIteratorに関する考察

モダンPHP勉強会に参加してきました。


名前空間のお話と、SPLのお話。

名前空間については、現在作っているFWでどうしようか悩み中なので、

PHP Standards Working Group の存在を知ったメリットは大きかった。

できる限り標準に合わせたいしね。
とはいえ、その中でも割れてるって。。。

んー、名前空間がアッパーキャメルケースなのも、ローワーケースなのもどちらも一長一短なのよね。



SPL については、 PHPらしからぬ拡張がまた面白いなぁと。

帰ってから気になって実行してみたのだけれど、
やっぱり、 InfiniteIterator と LimitIterator の組み合わせは可能だった。

コード

<?php
foreach(new LimitIterator(new InfiniteIterator(new ArrayIterator(array(1,2,3,4,5))), 3,4) as $i) { echo $i;}

結果

4512

ぱっと見遅延評価チックな事ができる。
まぁ、内部でどうやってるのか見てないけど、たぶん効率的なコードになっているわけじゃないんだろうなぁ。。。

ArrayIterator 実装して見りゃわかる事だけど、とりあえず眠いので明日にでも書こう。


と思ったのだけど、やっぱり気になって書いてみた。


コード

<?php
class InfiniteList implements Iterator {
	private $n;
	public function current () { return $this->n; }
	public function key () { return $this->n; }
	public function next () { $this->n++; echo "next: {$this->n}\n";}
	public function rewind () { $this->n=0; }
	public function valid () { return true; }
}
foreach (new LimitIterator(new InfiniteList(), 10, 1) as $i) {
	echo "echo: {$i}\n";
}

結果

next: 1
next: 2
next: 3
next: 4
next: 5
next: 6
next: 7
next: 8
next: 9
next: 10
echo: 10
next: 11


あー、なんというか、予想通り。

んでは、 SeekableIterator ならば?


コード

<?php
class SeekableInfiniteList implements SeekableIterator {
	private $n;
	public function seek ($position) { $this->n = $position; echo "seek:{$this->n}\n";}
	public function current () { return $this->n; }
	public function key () { return $this->n; }
	public function next () { $this->n++; echo "next: {$this->n}\n";}
	public function rewind () { $this->n=0; }
	public function valid () { return true; }
}

foreach (new LimitIterator(new SeekableInfiniteList(), 10, 1) as $i) {
	echo "echo: {$i}\n";
}

結果

seek:10
echo: 10
next: 11


おぉ。ちゃんとイテレータによって効率的な手段を選んでくれるのね。
んー。実装の仕方次第では結構使える気がする。



それにしても、この考えって、完全にSTLっつーか C++のぱくりだよね。
そのうち、Boost Range 的なものも出てくるのか……?w

#modernphp