こんにちは、@sugyanです。
先日、[/articles/advent-calendar/2010/sym/:title=sym track]にて"[/articles/advent-calendar/2010/sym/12:title=7種類の記号だけでPerlプログラムを書く]"という記事を書きまして、せっかくノウハウが出来たので一応モジュール化しておこうと思い"Acme::HeptaSymbolize"というものを作りました。
リポジトリはこちらです。 https://github.com/sugyan/Acme-HeptaSymbolize
特に依存は無いはずなのでサクっとインストールできると思います。
まぁ先に書いておきますと、ぶっちゃけAcme::Bleach系の自己書き換えモジュールです。 Acme::EyeDropsのようなものではありません。
例えば、こんなプログラムがあるとします。
#!/usr/bin/perl use strict; use warnings; for my $i (1 .. 100) { my $str = ''; $str .= 'Fizz' if $i % 3 == 0; $str .= 'Buzz' if $i % 5 == 0; print $str || $i, "\n"; }
所謂FizzBuzz問題ってやつですね。3の倍数であれば"Fizz"、5の倍数であれば"Buzz"、15の倍数であれば"FizzBuzz"、それ以外であればその数字を出力します。
$ perl fizzbuzz.pl 1 2 Fizz 4 Buzz Fizz 7 ...(中略) 94 Buzz Fizz 97 98 Fizz Buzz
さて、こんな普通のプログラムを書いても面白くも何ともないので、Acme::HeptaSymbolizeをuseして実行します。
$ perl -MAcme::HeptaSymbolize fizzbuzz.pl
実行すると、何も出力されずに終了します。何も起こっていないように見えますが、ソースコードが書き換わっています。
$ cat fizzbuzz.pl ~ ''=~(('(').((''=='').''^'^'^'.'^'~').('^'^(''=='').''^'='^')').('='^'^'^'.'^'(').('('^'^').('.'^'~'^(''=='').'').('('^'='^'~'^'.'^')').((''=='').''^'='^'.').('='^')'^(''=='').''^'('^'.').(')'^'^'^'~'^'(').('.'^'('^')').((''=='').''^'~'^')'^'.'^'=').('='^'~'^'('^(''=='').''^')').((''=='').''^'~'^'=').('('^')'^'.').(')'^'^'^'='^'(').('.'^'('^'^'^(''=='').'').(')'^(''=='').''^'^'^'(').('.'^')'^'(').('.'^'^').('='^'.'^'('^'^').((''=='').''^'~'^'=').('('^')'^'~'^'.'^'=').((''=='').''^'='^'('^'.').(')'^'.'^'='^(''=='').''^'~').('='^'~'^'('^')'^(''=='').'').('.'^'='^'('^'^').('^'^'~').((''=='').''^'='^')'^'~'^'(').('.'^'='^(''=='').''^'('^'~').((''=='').''^'='^'~').('('^(''=='').''^'.'^'^').('='^'^').('('^'='^'.'^'~'^(''=='').'').('='^'.'^'(').('('^(''=='').''^'='^'.').('.'^'='^'~'^')'^(''=='').'').('='^')'^'('^(''=='').''^'~').('='^'('^'^'^'.').('^'^'~').(')'^'^').((''=='').''^'~'^'.').('~'^'='^(''=='').'').((''=='').''^'^'^')'^'(').('.'^(''=='').''^'('^'^').('^'^'('^')'^(''=='').'').('('^'~'^(''=='').'').((''=='').''^'('^'='^'~'^')').('.'^'='^'(').((''=='').''^'('^'.'^'=').('('^(''=='').''^'.'^'=').(')'^(''=='').''^'~').((''=='').''^'^').('~'^'='^(''=='').'').('^'^'~').('='^'~'^'.').('~'^')'^'.').('^'^'~').('='^(''=='').''^'.'^'~').('='^(''=='').''^'(').((''=='').''^'.'^'('^'^').('~'^'^').('(').((''=='').'').('~'^'^').('.').('.').('~'^'^').((''=='').'').('('^')'^(''=='').'').('('^')'^(''=='').'').(')').('~'^'^').('='^(''=='').''^'.'^'~').('^'^(''=='').''^')'^'=').((''=='').''^'='^'('^'.').('^'^'~').('^'^'~').('^'^'~').('^'^'~').('.'^'~'^'=').('.'^')'^'~').('~'^'^').((''=='').''^'='^'~'^'.').('='^(''=='').''^'(').('('^'~'^(''=='').''^'='^')').((''=='').''^'.'^'~'^'='^'(').((''=='').''^'='^'~').('~'^'^').('=').('~'^'^').('~'^'^'^'.'^')').(')'^'.'^'^'^'~').('('^'='^'.').('.'^'='^'('^(''=='').'').('~'^'^').('~'^'^').('^'^'~').('~'^'^').('='^'.'^(''=='').''^'~').((''=='').''^'('^'=').('('^'~'^(''=='').''^'='^')').('('^'.'^(''=='').''^'~'^'=').('~'^(''=='').''^'=').('^'^'~').('.').('=').('^'^'~').('~'^')'^'.'^'^').(')'^'^'^(''=='').'').('.'^'('^'^'^(''=='').'').('='^'^'^'('^(''=='').'').('^'^'('^'='^(''=='').'').('.'^'~'^')'^'^').('^'^'~').((''=='').''^'^'^'.'^'(').('~'^(''=='').''^')').('^'^'~').('.'^(''=='').''^'='^'~').((''=='').''^'('^'=').('('^(''=='').''^'.'^'^').('^'^'~').((''=='').''^'='^')').('^'^'~').('='^'^'^'.'^'~').('^'^'~').('=').('=').('^'^'~').(')'^'('^(''=='').'').('('^'.'^'=').('.'^'='^(''=='').''^'(').('~'^'^').('^'^'~').('~'^'^').('~'^'^').('~'^'.'^'='^(''=='').'').('('^'='^(''=='').'').((''=='').''^'('^'='^')'^'~').('.'^'('^(''=='').''^'='^'~').('~'^(''=='').''^'=').('~'^'^').('.').('=').('~'^'^').(')'^'.'^'~'^'^').('('^'='^'~'^')').(')'^'~'^'.'^'='^(''=='').'').((''=='').''^'('^'^'^'=').('='^(''=='').''^'^'^'(').('~'^'.'^')'^'^').('^'^'~').('^'^(''=='').''^'.'^'(').('~'^')'^(''=='').'').('^'^'~').('.'^'='^'~'^(''=='').'').('('^'='^(''=='').'').('.'^(''=='').''^'^'^'(').('~'^'^').((''=='').''^')'^'=').('~'^'^').('='^'^'^'~'^'(').('~'^'^').('=').('=').('~'^'^').((''=='').''^'('^')').('='^'.'^'(').('='^(''=='').''^'('^'.').('^'^'~').('^'^'~').('^'^'~').('~'^'^').('^'^'.').('='^'~'^(''=='').'').('^'^(''=='').''^'.'^'(').(')'^(''=='').''^'^'^'(').((''=='').''^'('^'='^'~'^'.').('~'^'^').('='^'~'^(''=='').''^'.').('='^'('^(''=='').'').('('^'~'^')'^'='^(''=='').'').('.'^'('^'='^'~'^(''=='').'').('='^'~'^(''=='').'').('~'^'^').('^'^(''=='').''^'.'^'=').('='^(''=='').''^'^'^'.').('~'^'^').((''=='').''^'.'^'~'^'=').('='^(''=='').''^'(').('^'^'('^'.'^(''=='').'').('^'^'='^'~'^(''=='').'').('^'^'~').((''=='').''^'~'^'.'^'=').((''=='').''^'.'^'=').('.'^'~'^(''=='').''^'=').('='^'.'^(''=='').''^'~').(')'^'^'^(''=='').''^'(').('~'^'='^'.'^(''=='').'').('='^'.'^(''=='').'').('='^'('^'.').('('^'='^'.'^(''=='').'').('='^'~'^'.'^(''=='').'').(')'^'='^(''=='').''^'^'^'('^'.').('.'^'='^'('^(''=='').'').('='^'.'^(''=='').'').('='^(''=='').''^'('^'^'^'.'^')').(')'))
"'", "=", "~", "(", ")", "^", "."の7つの記号だけで書かれた1行だけのプログラムになっています。
でもちゃんと実行可能なPerlプログラムなので、これでも普通に実行して元のものと同じ結果が得られます。
$ perl fizzbuzz.pl 1 2 Fizz 4 Buzz Fizz 7 ...(中略) 94 Buzz Fizz 97 98 Fizz Buzz
安心ですね。
残念ながら戻せません。諦めて下さい。
というときは
$ cat fizzbuzz.pl | perl -MAcme::HeptaSymbolize
とかやれば良いんじゃないでしょうか。変換後のものがSTDOUTに出力され、元のものはそのままです。
もちろん、"-M"オプションじゃなく直接プログラム内でuseしてもOKです。
#!/usr/bin/perl use strict; use warnings; use Acme::HeptaSymbolize; for my $i (1 .. 100) { my $str = ''; $str .= 'Fizz' if $i % 3 == 0; $str .= 'Buzz' if $i % 5 == 0; print $str || $i, "\n"; }
$ perl fizzbuzz.pl $ cat fizzbuzz.pl ''=~(('(').('^'^'.'^(''=='').''^'~').('='^(''=='').''^'^'^')').('^'^'.'^'('^'=').('^'^'(').('~'^(''=='').''^'.').(')'^'('^'.'^'='^'~').((''=='').''^'='^'.').('.'^')'^(''=='').''^'('^'=').(')'^'('^'~'^'^').('.'^')'^'(').('.'^(''=='').''^')'^'='^'~').(')'^'('^'~'^(''=='').''^'=').('='^(''=='').''^'~').('.'^'('^')').('='^'^'^')'^'(').('^'^'.'^'('^(''=='').'').('^'^'('^(''=='').''^')').('.'^'('^')').('='^'^'^'.'^'(').((''=='').''^'^'^'('^')').('('^'^').('~'^'^').('^'^'.').('='^'^'^'('^'.').((''=='').''^'='^'~').('.'^'='^'('^')'^'~').((''=='').''^'='^'('^'.').('.'^(''=='').''^')'^'='^'~').((''=='').''^')'^'='^'('^'~').('('^'.'^'='^'^').('~'^'^').('='^(''=='').''^'~'^')'^'(').('('^'.'^'='^'~'^(''=='').'').('~'^(''=='').''^'=').((''=='').''^'.'^'^'^'(').('='^'^').('~'^'.'^(''=='').''^'('^'=').('='^'.'^'(').((''=='').''^'='^'.'^'(').('.'^(''=='').''^')'^'='^'~').('~'^'('^(''=='').''^')'^'=').('('^'='^'^'^'.').('^'^'~').('^'^')').((''=='').''^'.'^'~').('~'^(''=='').''^'=').('^'^')'^'('^(''=='').'').((''=='').''^'^'^'('^'.').('^'^'('^')'^(''=='').'').('('^'~'^(''=='').'').('('^'~'^(''=='').''^')'^'=').('.'^'='^'(').('='^(''=='').''^'('^'.').((''=='').''^'='^'.'^'(').((''=='').''^')'^'~'^'='^'.').(')'^'='^'('^(''=='').''^'~').('.'^'='^'('^'^').('^'^'~').('.'^'^'^(''=='').'').('='^'^').('='^'~'^'.').('^'^'='^'('^'.').('='^')'^'.').('='^'.'^')').((''=='').''^'.'^'~'^')').('='^'('^'.'^'^').('.'^'^').('.'^'('^(''=='').''^'~'^'=').('.'^'~'^(''=='').'').('^'^(''=='').''^'='^')'^'(').('~'^')'^'.').('~'^'='^'.').('('^'='^')'^'^').('^'^(''=='').'').('='^')'^'.'^'('^'~').('.'^(''=='').''^'('^'^').((''=='').''^'^'^'('^'=').('='^'.'^'^'^'(').('='^'.'^'(').('('^'='^(''=='').''^'.').('.'^'('^(''=='').''^'=').((''=='').''^')'^'~').((''=='').''^'^').('~'^'='^(''=='').'').('^'^'~').('~'^'='^'.').('~'^'.'^')').('^'^'~').('.'^(''=='').''^'='^'~').((''=='').''^'='^'(').('('^(''=='').''^'^'^'.').('^'^'~').('(').((''=='').'').('^'^'~').('.').('.').('~'^'^').((''=='').'').(')'^'('^(''=='').'').('('^')'^(''=='').'').(')').('~'^'^').((''=='').''^'~'^'.'^'=').('^'^'='^')'^(''=='').'').('.'^'='^(''=='').''^'(').('^'^'~').('~'^'^').('~'^'^').('~'^'^').('='^'~'^'.').('.'^')'^'~').('^'^'~').((''=='').''^'~'^'.'^'=').((''=='').''^'('^'=').((''=='').''^'('^'~'^'='^')').('='^'.'^'('^(''=='').''^'~').((''=='').''^'='^'~').('~'^'^').('=').('^'^'~').('~'^')'^'^'^'.').('~'^')'^'.'^'^').('='^'.'^'(').('='^'.'^(''=='').''^'(').('~'^'^').('^'^'~').('^'^'~').('^'^'~').('.'^(''=='').''^'='^'~').((''=='').''^'('^'=').('~'^'='^'('^')'^(''=='').'').('('^'='^'.'^'~'^(''=='').'').('='^'~'^(''=='').'').('~'^'^').('.').('=').('~'^'^').('.'^'~'^')'^'^').('^'^(''=='').''^')').('^'^'.'^'('^(''=='').'').((''=='').''^'^'^'('^'=').('^'^'('^'='^(''=='').'').('~'^'.'^')'^'^').('~'^'^').('^'^(''=='').''^'('^'.').(')'^(''=='').''^'~').('~'^'^').('~'^'.'^(''=='').''^'=').('='^'('^(''=='').'').('('^'.'^(''=='').''^'^').('~'^'^').(')'^(''=='').''^'=').('~'^'^').('~'^'^'^'='^'.').('^'^'~').('=').('=').('^'^'~').((''=='').''^')'^'(').('.'^'('^'=').('('^(''=='').''^'='^'.').('^'^'~').('~'^'^').('^'^'~').('^'^'~').((''=='').''^'='^'.'^'~').('='^(''=='').''^'(').((''=='').''^'='^'('^'~'^')').('.'^(''=='').''^'('^'='^'~').('~'^'='^(''=='').'').('~'^'^').('.').('=').('~'^'^').('.'^'~'^'^'^')').(')'^'('^'~'^'=').('~'^')'^'.'^'='^(''=='').'').('^'^'='^'('^(''=='').'').('='^'^'^(''=='').''^'(').('^'^'.'^')'^'~').('^'^'~').((''=='').''^'.'^'^'^'(').('~'^')'^(''=='').'').('^'^'~').('='^'~'^(''=='').''^'.').('='^(''=='').''^'(').((''=='').''^'^'^'.'^'(').('~'^'^').('='^(''=='').''^')').('^'^'~').('~'^'='^'^'^'(').('^'^'~').('=').('=').('~'^'^').('('^')'^(''=='').'').('('^'='^'.').('.'^'='^(''=='').''^'(').('^'^'~').('~'^'^').('^'^'~').('~'^'^').('^'^'.').((''=='').''^'~'^'=').((''=='').''^'('^'^'^'.').('('^'^'^(''=='').''^')').('.'^(''=='').''^'~'^'='^'(').('~'^'^').((''=='').''^'~'^'.'^'=').('='^'('^(''=='').'').('='^'~'^(''=='').''^'('^')').((''=='').''^'('^'.'^'~'^'=').('~'^'='^(''=='').'').('^'^'~').((''=='').''^'^'^'='^'.').('='^(''=='').''^'.'^'^').('~'^'^').('~'^(''=='').''^'.'^'=').((''=='').''^'='^'(').('^'^'('^(''=='').''^'.').('^'^(''=='').''^'='^'~').('~'^'^').('~'^'.'^(''=='').''^'=').((''=='').''^'.'^'=').('~'^(''=='').''^'.'^'=').((''=='').''^'.'^'='^'~').(')'^(''=='').''^'('^'^').((''=='').''^'='^'~'^'.').('.'^(''=='').''^'=').('.'^'='^'(').('='^'.'^(''=='').''^'(').((''=='').''^'.'^'='^'~').('('^'='^'^'^'.'^(''=='').''^')').('.'^(''=='').''^'('^'=').((''=='').''^'='^'.').('='^'^'^(''=='').''^'.'^')'^'(').(')')) $ perl fizzbuzz.pl 1 2 Fizz 4 Buzz Fizz 7 ...(中略) 94 Buzz Fizz 97 98 Fizz Buzz
変換後のコード内に'use Acme::HeptaSymbolize;'を実行する部分が含まれることになりますが、元々7記号のみのソースコードの場合は何もせずに処理を続行するようにしてあります。
importの引数に"qq"を渡せば、シングルクォートの代わりにダブルクォートを使うようになります。
$ cat fizzbuzz.pl | perl -MAcme::HeptaSymbolize=qq ~ ""=~(("(").("."^"^"^(""=="").""^"~").((""=="").""^"^"^"="^")").("^"^"("^"."^"=").("("^"^").((""=="").""^"."^"~").(")"^"("^"~"^"."^"=").((""=="").""^"."^"=").("."^(""=="").""^"="^"("^")").(")"^"~"^"^"^"(").(")"^"("^".").("~"^"."^(""=="").""^"="^")").("="^"~"^"("^(""=="").""^")").("~"^"="^(""=="")."").("("^")"^".").(")"^"("^"^"^"=").((""=="").""^"("^"^"^".").(")"^"("^(""=="").""^"^").(")"^"."^"(").("."^"^").("^"^"."^"="^"(").("="^(""=="").""^"~").("="^")"^"~"^"."^"(").("."^"="^"("^(""=="")."").("."^")"^"~"^(""=="").""^"=").((""=="").""^"("^"~"^"="^")").("^"^"("^"="^".").("~"^"^").("("^"="^")"^"~"^(""=="")."").("~"^"="^"."^"("^(""=="")."").((""=="").""^"="^"~").("^"^"."^(""=="").""^"(").("="^"^").("="^"("^(""=="").""^"~"^".").("."^"="^"(").("("^"="^"."^(""=="")."").("="^")"^"."^(""=="").""^"~").(")"^"~"^(""=="").""^"="^"(").("="^"("^"."^"^").("~"^"^").(")"^"^").("."^(""=="").""^"~").((""=="").""^"="^"~").("("^")"^"^"^(""=="")."").("."^(""=="").""^"("^"^").((""=="").""^"("^")"^"^").("~"^(""=="").""^"(").("~"^"="^(""=="").""^")"^"(").("("^"."^"=").((""=="").""^"("^"="^".").("("^"."^(""=="").""^"=").("~"^(""=="").""^")").((""=="").""^"^").("="^(""=="").""^"~").("~"^"^").("."^"="^"~").("."^"~"^")").("^"^"~").((""=="").""^"~"^"."^"=").((""=="").""^"="^"(").("("^(""=="").""^"."^"^").("~"^"^").("(").((""=="")."").("^"^"~").(".").(".").("~"^"^").((""=="")."").((""=="").""^"("^")").((""=="").""^")"^"(").(")").("~"^"^").((""=="").""^"."^"="^"~").("="^(""=="").""^")"^"^").((""=="").""^"."^"("^"=").("^"^"~").("^"^"~").("~"^"^").("^"^"~").("."^"~"^"=").(")"^"."^"~").("^"^"~").("="^"."^(""=="").""^"~").("="^(""=="").""^"(").(")"^"="^"~"^(""=="").""^"(").("="^(""=="").""^"~"^"."^"(").("="^(""=="").""^"~").("^"^"~").("=").("~"^"^").(")"^"."^"^"^"~").("."^"~"^")"^"^").("="^"("^".").("."^"("^"="^(""=="")."").("~"^"^").("^"^"~").("^"^"~").("^"^"~").((""=="").""^"="^"~"^".").("("^"="^(""=="")."").("("^"~"^")"^"="^(""=="")."").("="^"."^"("^"~"^(""=="")."").("="^"~"^(""=="")."").("^"^"~").(".").("=").("^"^"~").("."^"~"^"^"^")").((""=="").""^"^"^")").((""=="").""^"^"^"."^"(").("("^"^"^(""=="").""^"=").("="^"^"^"("^(""=="")."").("~"^"^"^"."^")").("~"^"^").("^"^"."^(""=="").""^"(").((""=="").""^")"^"~").("~"^"^").("~"^"."^(""=="").""^"=").("("^(""=="").""^"=").("^"^"."^"("^(""=="")."").("^"^"~").(")"^(""=="").""^"=").("^"^"~").("."^"~"^"="^"^").("~"^"^").("=").("=").("^"^"~").(")"^"("^(""=="")."").("("^"="^".").("."^(""=="").""^"="^"(").("^"^"~").("~"^"^").("~"^"^").("~"^"^").((""=="").""^"~"^"."^"=").("("^(""=="").""^"=").("~"^(""=="").""^"("^")"^"=").("~"^"("^(""=="").""^"."^"=").("~"^(""=="").""^"=").("~"^"^").(".").("=").("~"^"^").("^"^"~"^"."^")").("("^"~"^"="^")").("."^")"^"="^(""=="").""^"~").((""=="").""^"^"^"="^"(").("^"^"="^"("^(""=="")."").("~"^"^"^")"^".").("~"^"^").("^"^"."^"("^(""=="")."").((""=="").""^"~"^")").("^"^"~").("~"^"."^(""=="").""^"=").("="^(""=="").""^"(").((""=="").""^"("^"^"^".").("~"^"^").(")"^(""=="").""^"=").("^"^"~").("^"^"~"^"("^"=").("^"^"~").("=").("=").("^"^"~").(")"^(""=="").""^"(").("("^"="^".").((""=="").""^"("^"="^".").("~"^"^").("~"^"^").("^"^"~").("^"^"~").("."^"^").((""=="").""^"~"^"=").("."^"("^"^"^(""=="")."").((""=="").""^")"^"^"^"(").("("^"."^(""=="").""^"="^"~").("^"^"~").("="^(""=="").""^"."^"~").("("^(""=="").""^"=").("("^")"^"~"^"="^(""=="")."").("~"^"="^(""=="").""^"."^"(").((""=="").""^"~"^"=").("^"^"~").("="^"."^"^"^(""=="")."").((""=="").""^"="^"^"^".").("^"^"~").("~"^"="^(""=="").""^".").("="^(""=="").""^"(").("."^(""=="").""^"("^"^").((""=="").""^"~"^"="^"^").("^"^"~").("."^"="^"~"^(""=="")."").("."^(""=="").""^"=").("~"^(""=="").""^"="^".").("="^"~"^"."^(""=="")."").(")"^"^"^"("^(""=="")."").("."^"~"^"="^(""=="")."").((""=="").""^"."^"=").("."^"("^"=").("="^(""=="").""^"("^".").((""=="").""^"="^"~"^".").(")"^"^"^"."^"("^(""=="").""^"=").("("^"."^(""=="").""^"=").("="^"."^(""=="")."").("."^"^"^(""=="").""^"("^"="^")").(")"))
いちおう他のAcme::Bleach系モジュールと違って変換後のプログラムに'use Hogehoge;'の行が必要ない、というのが強みです。
ほとんど使い所が無いモジュールだと思いますが… '$'や'@'や'%'などの記号が見飽きた、というときにでも使ってみたらいいんじゃないでしょうか。
一応すべて1行で出力されるので何でもワンライナーに出来る、という使い方もアリかも知れません。