YAPC::Kyoto 2023ノベルティのPerl Poemを読み解く

チーフエンジニア兼エンジニアリングマネージャのid:taraoです。先日開催されたYAPC::Kyoto 2023にはたくさんの方にご参加いただけまして、ありがとうございました。

トートバッグに書かれたPerlコード

YAPC::Kyoto 2023には、はてなもスポンサーとして参加しており、会場で配布されたトートバッグのデザインも提供していました。そのバッグの片面にPerlのコードが書かれていたことにはお気づきいただけたでしょうか?

コードを書き写すと以下のようになります。

use feature qw(try);

try {
  Something->new;
} catch ($your_dream) {
  tell $your_dream
    and seek our $future,
  @ YAPC::Kyoto, 2023;
}

今回のカンファレンスのテーマは「try/catch」だったので、それに沿った内容になっています。tell $your_dreamは、登壇者には発表を通して、参加者にはブログなどで語ってほしいという意味を込めています。

Perl Poetry

このコードは実はエラーなく実行できます。

$ perl yapc_kyoto_2023.pl
try/catch is experimental at yapc_kyoto_2023.pl line 3.
try/catch is experimental at yapc_kyoto_2023.pl line 5.
$ echo $?
0

このように、なんとなく自然言語として読める感じになっているのにPerlのコードとして合法(perl -csyntax okが返る・エラーなく実行できる)なもののことをPerl Poetryと言います*1

世の中のPerl Poetryの様子はこちらのスライドを見るとわかると思います。

実用的なコードに使われている例もあります。


コードを読み解く

せっかくなので、今回のコードを合法なPerlコードとして解釈するとどうなるのか見ていきましょう。

1行目

use feature qw(try);

これによりPerl 5.34から実験的に利用可能になったtry/catch構文が有効になります。

3~4行目

try {
  Something->new;

Somethingというパッケージはロードしておらず、->newの呼び出しはエラーになりますが構文としては合法で、tryの中なので実行時エラーがcatchされます。

5行目

} catch ($your_dream) {

4行目で発生したエラーを$your_dreamという変数でcatchしています。$your_dreamには"Can't locate object method \"new\" via package \"Something\" (perhaps you forgot to load \"Something\"?) at yapc_kyoto_2023.pl line 4.\n"という文字列が入っています。

変数名の部分は構文上$で始まっている必要があり(@ではダメで)、mylocalをつけることもできずレキシカル変数に限定されているようです。

6~8行目

難しいですが、use warningsすると少し雰囲気がわかります。

$ perl yapc_kyoto_2023.pl
try/catch is experimental at yapc_kyoto_2023.pl line 3.
try/catch is experimental at yapc_kyoto_2023.pl line 5.
Name "YAPC::Kyoto" used only once: possible typo at yapc_kyoto_2023.pl line 8.
tell() on unopened filehandle at yapc_kyoto_2023.pl line 6.
Use of uninitialized value $future in ref-to-glob cast at yapc_kyoto_2023.pl line 6.
seek() on unopened filehandle at yapc_kyoto_2023.pl line 6.

まず6行目は明らかにファイルハンドルではないもの(文字列)を渡しています。

  tell $your_dream

結果は-1が返るものの、これは組み込み関数tellの想定された挙動です。

続く7~8行目は組み込み関数seekの呼び出しです。seekは3引数関数です。

    and seek our $future,

第1引数のour $futureはファイルハンドルではないためuse warningsしていると警告が出ますが、構文としては合法です。openだったらこのような書き方をしますよね。

第2引数は一見どういうことなのかわからないかもしれません。

  @ YAPC::Kyoto, 2023;

Name "YAPC::Kyoto" used only onceの警告がヒントになってますが、実はこれ@YAPC::Kyotoという変数(YAPCパッケージのグローバル変数@Kyoto)として解釈されます。ここにスペース入れても大丈夫なんですね! 僕も知りませんでした。ちなみにこの部分のコードを考えたのはCTOのid:motemenです。

第3引数は単に2023という数値ですね。

seekは失敗しても偽が返るだけで、引数がデタラメでも実行はできます。

これでめでたくこのコードがエラーなく実行できることが確かめられました。

おわりに

これくらいのちょっとしたコードでも、Perl Poetryを読み書きするといろいろ知らなかった点が発見できて面白いですね。みなさんも是非Perl Poetryに挑戦してみてください。

今回のコードはid:nagayama, id:motemen, id:taraoで考えました。

*1:概念が"Perl Poetry"で1編のコードは"Perl Poem"です