Perl最短
一番簡単なquineはコレ?
open 0;print<0>
ただ、これは標準入力からだとダメなのでpipeで繋げる使い方はできない。
$ cat quine.pl open 0;print<0> $ perl quine.pl open 0;print<0> $ perl quine.pl | perl $
print+eval
pipeでも使えるようにするには、こういう書き方がある
$_=q{print"\$_=q{$_};eval"};eval
これなら何度でもpipeで繋げられる。
$ cat quine2.pl $_=q{print"\$_=q{$_};eval"};eval $ cat quine2.pl | perl $_=q{print"\$_=q{$_};eval"};eval $ cat quine2.pl | perl | perl $_=q{print"\$_=q{$_};eval"};eval
引数を明示的に与える方式だとこう?
$ cat quine3.pl eval($_=q{print"eval(\$_=q{$_})"}) $ cat quine3.pl | perl eval($_=q{print"eval(\$_=q{$_})"}) $ cat quine3.pl | perl | perl eval($_=q{print"eval(\$_=q{$_})"})
おそらくこれが、eval使える言語では結構一般的に使われているquineのテクニック。
Quine ruBy Perl版 - すぎゃーんメモも、これに色々手を加えた形で作っている。
記号化
evalと言えば記号プログラミング。上記のを
$_=';eval{print"\$_=".chr(39).$_.chr(39).$_}';eval{print"\$_=".chr(39).$_.chr(39).$_}
と変形。evalする部分を拡張正規表現記法にし、("$_"はうまく動かないので適当な特殊変数におきかえ)
$^=';""=~/(?{print"\$^=".chr(39).$^.chr(39).$^})/';""=~/(?{print"\$^=".chr(39).$^.chr(39).$^})/
文字列化
$^=';""=~("(?{".q{print"\$^=".chr(39).$^.chr(39).$^}."})")';""=~("(?{".q{print"\$^=".chr(39).$^.chr(39).$^}."})")
排他的論理和に置換
$^=';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")
で、できあがり。
$ cat quine4.pl $^=';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})") $ cat quine4.pl | perl $^=';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})") $ cat quine4.pl | perl | perl $^=';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")';""=~("(?{".("__).+_}_#}_"^"/-@\@_}!{}@}").".".("}[_"^"_|}").".".("_}"^"{#").".".("}|_"^"_[}").".".("_#"^"{}")."})")