PHPにリストアロケーターとジェネレーターがある場合

数週間前、PHPメーリングリストで、 ジェネレーター、式ジェネレーター、およびリストの割り当てについて説明したハッキングに関する興味深い提案がありました。 PHPのコア開発者やユーザーのように、一部の人々がこの提案の見通しについて確信を持っていないことは驚くことではありません。 私はいくつかのアイデアを共有し、これらの人々を説得してみたいと思います。



XML宣言的解析



最も簡単な例は、大きなXMLファイルを解析するためのシンプルなインターフェイスです。



<?php function *readXML($file) { $r = new XMLReader; $r->open($file); while($r->read()) { yield $r; } } function *filterNodes(callable $predicate, $nodes) { foreach($nodes as $node) if($predicate($node)) yield $node; } function matchName($name) { return function($node) use($name) { return $node->name === $name; }; }
      
      





そして、これらの関数を使用した構文解析の可能な変形。



 <?php function *getArticlesFromXML($file) { foreach(filterNodes(matchName('article'), readXML($file)) as $node) yield nodeToArticle($node); } function nodeToArticle($node) { // transform node return $node->name; } $articles = [foreach(getArticlesFromXML('data.xml') as $article) yield $article];
      
      





すでにXMLReader



を使用している人は、解析制御がwhile



からどのように取られ、高階関数を使用して宣言スタイルに「調整」されるかを理解するはずです。



イテレータのシンプルな装飾



これは一般的なパターンではありませんが、外部サービスと通信する必要がある場合、その答えを2つの部分にまとめたいと思います。







私が言ったように、私は他の誰かのコードに似たようなものを見ませんでしたが、私にとっては、ジェネレーターを使用する方が簡単になった頻繁なパターンです。



 <?php // inside some class public function getResult() { return SomeCustomIterator($this->results, new SomeCustomDecorator); } // with generators public function *getResults() { foreach($this->results as $result) yield new SomeCustomDecorator($result); }
      
      







さらに表現力豊かなAPI



レイジーコンピューティング、ジェネレーターの基本原理、ほとんどのPHP開発者のあまり使用されていないプログラミングスタイル。この機会がPHPに取り入れられた場合、人々がどのように掘り下げていくのかを見てみたい。



混合スタイル(OOPと手続き型プログラミング)を使用する人々を想像するのは難しくありません。 たとえば、次のような単純なものから始めることができます。



 <?php function select() { return func_get_args(); } function from($source) { return $source; } function where() { return func_get_args(); } function *query($select, $from, $where) { foreach($from as $element) { foreach($where as $predicate) { if(false === $predicate($element)) continue 2; } $fields = array(); foreach($select as $selector) { $fields[] = $selector($element); } yield $fields; } } $articles = query( select(property('name')), from(readXML('data.xml')), where(matchName('article')) ); // where property could be something as simple as function property($name) { return function($node) use ($name) { return $node->{$name}; }; }
      
      





または、LINQのようなものを構築することもできますか? それは既に存在しません



Pythonのように見える



人々がこの側面に気づき、反対したというコメントがいくつかありました。 私は当時理解していなかったし、なぜこれが悪いのか理解していません。 たとえば、私はこの良いニュースを考慮します。完璧な言語はなく、それぞれが他の人に役立つ機能を含めるようにすべきです(もちろん、実装の可能性を考えると)。



自分でテストする



これらの行の前に記事を読み、興味を失っていない場合は、タブを閉じる前に、ターミナルに移動して次のコマンドを実行することをお勧めします。



 $ git clone -b addListComprehensions https://github.com/nikic/php-src.git $ cd php-src $ ./buildconf $ ./configure $ make cli $ ./sapi/cli/php some-example-file.php
      
      






All Articles