これは実際にはかなり単純な JAPH です。その最大の特徴は、「画像」の大部分を占めるデータ列の分割と、半再帰的な印刷です。
これは、フォーマットをクリーンアップしたときに取得するコードです
my ($j,$a,$p,$h);
$j = sub {
print( chr( $p += $a->[$h++] ) );
$j
};
;;
$a = [0, split "[: \n]+", # the split regex
q/43 -002:1 # input string start: q/ ...
-084 065:13
0001 000005
-0012 -00003
000013 -82 00048
21:13:-6.00:-76:72
-007.:02:00008.00
:::-6.00:::013
-70:3::-70:.64
/]; # input string end: .../
# print Dumper $a; # <--- this is my line
$p = 0x4a;;
$h=0;
$j->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->()->();
最初の部分は、4 つの主要な変数の宣言と割り当てです。
$j
$j
文字を出力し、それ自体への参照を返すコード参照です。印刷はいくつかのステップで構成されています。
$a->[$h++]
配列を繰り返し処理し、@$a
1 つの要素を返します
$p += ...
その要素が追加されます$p
print chr( $p ... )
その後$p
、 chr() に返され、結果の文字が出力されます。
サブブロックの最後は です$j
。これは、各反復を意味し、サブの戻り値はそれ自体への参照になります。これは、半再帰機能を可能にする部分です。
$a
$a
0 と入力文字列の分割の結果で構成される配列への参照です。ここでも、1 行のコードでいくつかのことが起こっています。
q/43 .../
これは、区切り文字スラッシュを含む通常のq()
一重引用符で囲まれた文字列/
です。]
配列参照を示す閉じ括弧の直前で終了します。
split "[: \n]+",
これは文字クラスの分割であり、1 回以上繰り返されます。JAPH 自体のスペースを埋めるために、その中に余分なスペースがあります (ここでは削除しました)。基本的に、これによりすべてのコロン、スペース、および改行が削除され、結果のリストが返されます。
$a = [0, ... ]
分割のリストは0
(1 つの要素のみ) のリストに追加され、配列参照を示すためにすべてが角かっこで囲まれ、$a
.
0
コードに1回限りのエラーがあるため、リストは で始まると思い$p
ます。元の値は出力の最初の文字です。
これは次のData::Dumper
出力です$a
。
$VAR1 = [
0,
'43',
'-002',
'1',
'-084',
'065',
'13',
'0001',
'000005',
'-0012',
'-00003',
'000013',
'-82',
'00048',
'21',
'13',
'-6.00',
'-76',
'72',
'-007.',
'02',
'00008.00',
'-6.00',
'013',
'-70',
'3',
'-70',
'.64'
];
$p と $h
$p
と$h
は数値のみであり、これにおけるそれらの役割は、それぞれ関数のソース番号と配列chr()
の反復子です。@$a
最後の行は、$j
サブルーチンが実行され、JAPH が出力される部分です。連鎖->()
構文は、前の各反復の戻り値が次の実行に使用されることを意味します。そして$j
、それ自体への参照を返します。これにより、半再帰的な問題が発生し、値のみが変更されます。
これを行うのと似ていると思います:
$x = $j->();
$y = $x->();
$z = $y->();
...
それでは、最初のいくつかの手順を見てみましょう
$j->()
実行
$a->[$h++]
$h
は 1 にインクリメントされ、サブストリップに 0 を返します。$a
サブストリップは の最初の要素である を返し$a
ます0
。
$p += 0
これ0
を に加算し、 (74)$p
の値を chr に戻します。$p
print chr(74)
これによりJ
、標準出力に a が出力されるようになりました
$j
返されます。
->()
戻り値に対して別の実行が実行されるため、$j
再度実行されます。
$a->[$h++]
$h
は 2 にインクリメントされ、1$a
が返され、2 番目の要素である が返されます43
。
$p += 43
74 + 43 = 117 が返されますchr
print chr(117)
これは印刷しますu
の要素は$a
正と負の両方であり、必要な場所に数値を移動します。最終的に、印刷されたすべての文字は次のようになります。Just another Perl hacker,
最初の10回の実行の概要は次のとおりです。
p => 74 += 0 = 74 output => chr( 74) J
p => 74 += 43 = 117 output => chr(117) u
p => 117 += -002 = 115 output => chr(115) s
p => 115 += 1 = 116 output => chr(116) t
p => 116 += -084 = 32 output => chr( 32)
p => 32 += 065 = 97 output => chr( 97) a
p => 97 += 13 = 110 output => chr(110) n
p => 110 += 0001 = 111 output => chr(111) o
p => 111 += 000005 = 116 output => chr(116) t
p => 116 += -0012 = 104 output => chr(104) h