Self Reference
http://d.hatena.ne.jp/TAKESAKO/20090716/1247750262
via http://d.hatena.ne.jp/sugyan/20090717/1247842750
を見て、なんか書いてみるかなぁと。下記3つのコードは一定の期間をおいて SEGV するコードなのですが、共通のテーマに基づいて書かれてます。 SEGV の理由は何でしょうか。
一個目。邪道。でもゴルフでたまに使えるんだよね。
''=~('(?{'.('_/_ '^';@{:').'})')
二個目。一番短いけどこの挙動は長い間知らなかったので結構わからん人多いんじゃないかな。
$_=~'(?{$_=~""})'
三個目。読むのはそんなに難しくないけど、書くのは結構大変。新しく書こうと思ったけど結局使い回しでいいやという。
($;=<<'' _(_@{**+(\$;=<<'' $; )=~(' _ ^-^,'^'"`[;[?@(\$;^":^>,[[[")})')+ )=~(' _ ^-^,'^'"`[;[?@($;^":^>,[[[")})')
stack overflow
まぁ 3 つとも stack overflow してるわけですが、題字の通り自己参照に思いをはせていたのでした。ゲーデルエッシャーバッハをチマチマ読んでることが関係していると思われる。本当は無限ループになると思って書き始めたのだけど、正規表現を実行する部分がどうしても再帰になってしまって、stack 使い切ってしまうのだった。
一個目はデコードすると単に do$0 。自分読む一番ダサい方法だと思う。
二個目は
http://d.hatena.ne.jp/shinichiro_h/20070119#1169154728
で教えてもらった前回マッチした正規表現を使う機能で、正規表現内に埋められた実行コードを再帰的に実行してます。なんというか実行してる段階ではマッチしてない気がするんだけど、なんでうまくいくんかなぁという疑問が。
三個目は、デコードすると、
eval $;^XXX
みたいな文字列が出てくるはずで、この中の $;^XXX の部分は計算すると
($;=<<'' _(_@{**+(\$;=<<'' $; )=~(' _ ^-^,'^'"`[;[?@(\$;^":^>,[[[")})')+ )=~(' _ ^-^,'^'"`[;[?@($;^":^>,[[[")})')
になってるはずです。つまり自分を生成した後で eval してるので無限実行。
これ最初は printf 使ったパターンで一行に押し込められないかなぁとあれこれやってたのですがよく考えると %c の c が大変うっとうしいというか quine 的に無理ゲーぽかったので、昔書いたのを使い回して良いことにしてしまったのでした。
http://d.hatena.ne.jp/shinichiro_h/20071017#1192627447
やまぁ一行に押し込めるのも当然できるんだろうけど。
追記: にはさんがわかりやすい解説を書いてくれていました。