〜generatorを添えて〜みなさん、こんにちは。今日は新春ということで、fizzbuzzについてお話します。世の中には大きくわけて2つのfizzbuzzがあります。一つ目はテスト書ける系fizzbuzzです。一つはテスト書けない系fizzbuzzです。今日はみなさんに併せて3種類のfizzbuzzの実装をお見せして、テスト書ける系fizzbuzzにgeneratorを用いると、どのような利点が生まれるかご紹介します。ちなみに研修でロジカルシンキングおじさんに生まれ変わったので、話し方がロジカルになりました。ごちゃまぜfizzbuzzまずテスト書けない系fizzbuzz筆頭の普通のfizzbuzz。}}fizzbuzz(100);これでも動きますが、これではテストが書けません。文字列fizzbuzz上記の反省を活かしてテスト書ける系fizzbuzzを書いてみましょう。思いつくのは"1\n2\nFizz\n"...といった文字列を返却するstring_fizzbuzzメソッドを呼び出し、それを表示する方法です。print(string_fizzbuzz($n));}fizzbuzz(100);これでOKです。string_fizzbuzzで返された文字列を検査することで、printの出力先や、print自体のバグに悩まされること無く、fizzbuzzのロジック部分をテストすることができます。ジェネレータfizzbuzzstring_fizzbuzzでは、ロジック部分と出力部分を分離することによってテストが可能になりました。fizzbuzzの最終値がとても大きい場合や、各$iにおいてfizzbuzz内で返す値を決めるのに時間がかかる場合に、ちょっと面倒なことになります。例として、下記のような処理を考えます。すごく大きな値fizzbuzz(9999....);このような場合、実際に値が表示されるのは、重い処理が9999....回終わったあとになります。最初の方の結果を見るのに長い時間待たされる上に、途中でエラーが落ちてシステムがクラッシュしたら途中までの値を見ることもできません。9999.....個分という巨大なfizzbuzz文字列を格納するためのメモリ消費も、本質的には必要のないコストです。このようなつらい事態を回避するために、generatorを使うことが出来ます。コードは下記のようになります。}}fizzbuzz(100);このコードでは、generator_fizzbuzz呼び出し時にyieldまで実行が進み、yieldで指定された値が返り値として返却される→返却された値がfizzbuzz関数内でprintされる。いう処理が行われます。printした後の処理ですが、fizzbuzz内で$g->next()されると、先ほど中断したところ(yieldの次の行から)から再度実行が始まります。このようにfizzbuzzの実装にgeneratorを用いることで、テストが書ける構造は維持した上でfizzbuzzを最後まで処理しなくても値を1つずつ表示できるため待たなくて良い。巨大な文字列をメモリに格納しなくてもよい。いった時間やメモリに関する面での性能を改善することができます。まとめテスト書けない系fizzbuzzを見てもまさかりを投げてはいけない。*1:配列を返した方が色々良さそうですが、そこは一旦置いておきます。Languageを触ってみたのでメモを残します。»プロフィール間違ったことが書いてあったら@matsu_charaまでご連絡ください。Languageに入門(3)はてなブログをはじめよう!matsu_charaさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。