PHPのジェネレータ
アッ (活用するの忘れてた感)
これを! (↓↓Iteratorインタフェースの実装例↓↓)
<?php // ファイルの行データの読み込みクラス class FileLineIterator implements Iterator { private $fp = null; private $line = null; public function __construct($filepath) { $this->fp = fopen($filepath, "rb"); } public function __destruct() { @fclose($this->fp); } public function current() { return $this->line; } public function key() { throw new BadFunctionCallException(); } public function next() { $this->line = fgets($this->fp); return $this->line; } public function rewind() { return rewind($this->fp); } public function valid() { return (!is_null($this->fp) && $this->line !== false); } } // 処理の開始 $num = 1; $iterator = new FileLineIterator($argv[1]); foreach($iterator as $line) { // ここで行番号を出力する printf("%5d: %s", $num++, $line); }
こうや!(↓↓yield()↓↓↓)
<?php // ファイルの行データの読み込み関数 function file_get_lines($filepath) { $lines = array(); $fp = fopen($filepath, "rb"); while(($line = fgets($fp)) !== false) { // yieldキーワードで$lineを都度返却することができる yield $line; } fclose($fp); } // 処理の開始 $num = 1; foreach(file_get_lines($argv[1]) as $line) { // ここで行番号を出力する printf("%5d: %s", $num++, $line); }
ということです。
でっかい配列変数に展開するとメモリを喰い、Iteratorをimplementすると大げさで遅いし、という事で。
途中結果をreturnして値の供給を続けるやつ。
yield ... 産出する,(利益が)出る, (相手に)屈服する
次のようにも書けるので、foreach()を使った既存の記述も置き換えやすいですね。そうですね。
<?php // ファイルの行データの読み込み関数 function file_get_lines($filepath) { $lines = array(); $fp = fopen($filepath, "rb"); while(($line = fgets($fp)) !== false) { // yieldキーワードで$lineを都度返却することができる yield $line; } fclose($fp); } $f = file_get_lines($argv[1]); // 処理の開始 $num = 1; foreach($f as $line) { // ここで行番号を出力する printf("%5d: %s", $num++, $line); }