LoginSignup
21
18

More than 5 years have passed since last update.

ジェネレータ関数のDocコメントのreturnタグは何と書けばよいか

Last updated at Posted at 2016-04-07

PHP 5.5で導入されたジェネレータ、便利です。

ジェネレータを使ったコードをいくつか書いたのですが、ふと気になることができました。
それは、ジェネレータ関数の「返値の型」は何なのか、ということです。

たとえば、

function stringGenerator()
{
  yield 'string';
}

というジェネレータ関数を作ったとします。
ジェネレータ関数も関数なので、Docコメントで関数の説明を書きましょう。

/**
 * 文字列をyieldするジェネレータ
 *
 * @return 型 返値の説明
 */
function stringGenerator()
{
  yield 'string';
}

ここで疑問が生じます。
@returnタグの「型」には何と書くのがよいのでしょうか。
string? それとも、\Generator

調査

過去の自分のコードを見返してみる

試しに私が過去に書いたコードのジェネレータ関数のDocコメントを見返してみると、
@return \Generator 返値の説明(※文字列をyieldする)
という記述と
@return string 返値の説明(※ジェネレータなので必ずforeach等で受けること)
という記述と両方あって、統一されていませんでした。
これまであまり深く考えたことがなかったので仕方ありませんが、これではいけません。統一した書式を決めなければ。

PHPのマニュアルを調べる

PHPマニュアルの「ジェネレータとは」のページの「Generator オブジェクト」の節によれば、

ジェネレータ関数を最初に呼んだときには、内部クラス Generator のオブジェクトを返します。

とのことなので、ジェネレータ関数の「返値の型」は\Generatorクラスのオブジェクトであり、Docコメントの@returnタグは
@return \Generator 返値の説明
とするのが正解な気がします。

しかし、yieldした値の型が分からないのは何とも不便です。
@return string 返値の説明
と書きたくなります。ですが、これだとreturn文で文字列値を返す普通の関数と見分けがつきません。

phpDocumentorのマニュアルを調べる

ジェネレータ関数の「返値の型」が\Generatorオブジェクトであるとして、yieldされる値をそのオブジェクトの要素と考えればどうでしょう。

配列であれば、型をarrayで表すこともできますし、要素が文字列の配列ならstring[]、整数の配列ならint[]のように、要素の型[]の形で表すこともできます。

同じようにして、\Generatorオブジェクトと、yieldされる値の型を同時に表すことはできないでしょうか。

そこで、phpDocumentorのマニュアルには何と書いてあるだろうかと、phpDocumentorマニュアルの「Types」のページを見てみました。しかし、それらしい記述は見つかりませんでした。

PSRを調べる

それではPHPのコーディング規約であるPSRに何かないかと見てみると、まだ草案(Draft)ではありますが、PSR-5でPHPDocの書き方を定めているとのこと。GitHubにある「PSR-5: PHPDoc」の草案を見てみると、使えそうなものが見つかりました。

それが、「Collections」です。

たとえば、\ArrayObjectというクラスのオブジェクトがあり、それが文字列型の要素を持っているとします。これの「型」を、Collectionsでは\ArrayObject<string>と書くようです。

これを応用すれば、文字列値をyieldするジェネレータ関数の「返値の型」は、文字列型の要素を持つ\Generatorオブジェクトであると考えて、\Generator<string>と表せそうです。つまり、Docコメントの@returnタグは、
@return \Generator<string> 返値の説明
と書けそうです。

結論

ジェネレータ関数のDocコメントの@returnタグは、
@return \Generator<yieldする値の型> 返値の説明
のように書くことにします。

補足

  • 上記PSR-5の「Collections」では、オブジェクトの要素のキーの型を指定する方法も示されていました。たとえば、整数値のキーを持つ文字列値を要素に持つ\ArrayObjectオブジェクトは\ArrayObject<int, string>のように表すようです。これを用いれば、yield $key => $value;というジェネレータ関数のDocコメントの@returnタグは、@return \Generator<$keyの型, $valueの型> 説明のように書けそうです。
  • この記事を執筆する(2016年4月8日)よりも前の2013年~2015年に、phpDocumentorのGitHubリポジトリにIssueが立てられ既に同様の議論が行われていたようです。こちらでも、本稿と同様@return \Generator@return \Generator<string>のように表すのがよいだろうという話のようでした。中にはGenerator::current()の返値の型VGenerator::key()の返値の型KGenerator::send()の返値の型SGenerator::getReturn()の返値の型Rを使ってGenerator<V, K, S, R>と表すべきだとの意見もありましたが、さすがにそれは面倒臭いなという印象を受けました。また、@returnタグの代わりに@yieldタグを新設すべきだという意見も出ていましたが流れてしまったようです。なかなか難しい問題ですね。
  • PSR-5がまだ「Draft」(草案)であることには十分注意する必要があると思います。
    2017年10月に、PSR-5の策定状況が「Draft」から「Abandoned」(放棄)に変更されました。
    2018年9月26日に、PSR-5は再び「Draft」になりました。また、PSR-5は分割され、PSR-5とPSR-19の2つのPSRになりました。分割後のPSR-5はPHPDocの書式を規定し、PSR-19はタグの一覧を規定します。

参考文献

関連記事

  • tadasan『2018年のPHPDoc事情とPSR-5』
    本記事とは直接関係ありませんが、PHPDocの状況についてまとめてくださっています(2018年3月現在の情報)。この記事でPSR-5が放棄されたのを知りました。
21
18
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
18