AspectMockを使うクラスでyieldを使ってるとき

AspectMockでモッキングするクラス(に依存するクラス)でyieldを使ってると、AspectMockが注入するコードがreturnで値を返そうとするためエラーになる。

PHP Fatal error:  Generators cannot return values using "return" in /...

とりあえずキャッシュコードのreturnをyieldに変えて動かしてたけど、もうissueになっててdev-masterでは解消されているっぽい。

Generators result in fatal error · Issue #50 · Codeception/AspectMock

Composerでdev-masterのモジュールをインストールする(”minimum-stability”: “dev”にしてもいいけどこれだと全モジュールのdev-masterが入る)

"require-dev": {
   ...
   "codeception/aspect-mock": "dev-master"
   ...
}

上記修正は返り値のキーワードをPHPDOCの@returnで判別するものなので、AspectMockのキャッシュを消して、yieldを使ってるメソッドのPHPDOCの@returnに \Generator を書く(Generatorだけだとだめだった)

/**
 * @param $name
 * @return \Generator
 */
public function generatorMethod($name)

これで動いた。AspectMock黒魔術感あってハマると苦しい…。


Adobe-Japan1-6に収録された文字にマッチする正規表現

仕事で対象のテキストがいわゆるAdobe-Japan1-6(Adobeが定めたDTP向けの文字集合規格)の収録文字かどうかをチェックする機能を実装することになって、どうしようかなと思ったんだけどとりあえず安直に正規表現でマッチさせることにした。

AJ1-6のunicode一覧はもらったのでこれを最初Regexp::Assemble(のPHP実装)に全部食わせてunicode16進コードがAJ1-6にマッチする正規表現

(?-xism:x\{(?:6(?:1(?:1[012345679ABCEF]|7[012345678BCDEF]|C[01236789ABCDEF]|0[01236789ACDEF]|4[12456789ABCDE]|9...(こんな感じ)

をつくったんだけど、よく考えたらこれだとテキストを1文字づつ16進コードに変えてテストしないといけなくてあんま正規表現の意味がないことに後から気づいたので、たんに文字クラスに\x{}で表したunicode文字を並べた(いちおうコードが連続しているところは\x{}-\x{}と省略するようにした)正規表現

[\x{0020}-\x{005B}\x{00A5}\x{005D}-\x{007B}\x{00A6}\x{007D}\x{02DC}\x{02BC}\x{005C}\x{02BB}\x{007C}\x{007E}\x{00A1}-\x{00A3}\x{2044}\x{0192}\x{00A7}\x{00A4}\x{201C}\x{00AB}\x{2039}-\x{203A}\x{2013}\x{00B7}\x{00B6}\x{2022}\x{201A}\x{201E}\x{201D}\x{00BB}...(こんな感じ)

に切り替えた。正規表現だけで11万文字以上になってしまいこれ動くのかなと思ったけどいまのところ動いている。PHPは複雑な正規表現を大量のテキストにマッチさせようとするとSegmentation Faultで落ちることがあるのであんまよくない気もするけど、文字クラスのテーブルが巨大なだけでパターンとしては複雑じゃないので大丈夫、だといいな。