Acme::HeptaSymbolizeで7記号プログラミング

sugyan
2010-12-20

こんにちは、@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に出力され、元のものはそのままです。

■プログラム内でuseしても大丈夫

もちろん、"-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行で出力されるので何でもワンライナーに出来る、という使い方もアリかも知れません。