Acme-EyeDrops-1.16 > Acme::EyeDrops

名前

Acme::EyeDrops - Perlにおけるビジュアル・プログラミング(Visual Programming)

概要

    use Acme::EyeDrops qw(sightly);

    print sightly( { Shape       => 'camel',
                     SourceFile  => 'eyesore.pl' } );

説明

Acme::EyeDropsは、同等の、それでいて見苦しい文字や数字が一切ない ものに変換します。

ビジュアル・プログラミング(Visual Programming)によるブレークスルーにおいて、 EyeDropsにより作成されたプログラムをUMLダイアグラムのような様々な形に 吐き出させることにより、その新しく改良された視覚的表現を一目見るだけで、 そのプログラムがどのように機能するかをすぐに理解できるようにします。

Acme::Smirchには似ていますが、Acme::BleachAcme::Buffyとは 違い、生成されたプログラムはターゲット・システムにAcme::EyeDropsを インストールすることを必要としないで走ります。

利用例

以下のようなコードが入っている、helloworld.plというプログラムを 持っているとします:

    print "hello world\n";

以下のようにすることで、このプログラムをラクダに見えるようにすることが できます:

    print sightly( { Shape       => 'camel',
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

上記のAPIを使う代わりに、demoディレクトリにあるsightly.plコマンドを 使うほうが便利だと思うかもしれません:

    sightly.pl -h           (ヘルプ)
    sightly.pl -s camel -f helloworld.pl -r >new.pl
    cat new.pl              (ラクダのようにみえるはず)
    perl new.pl             (前と同じように"hello world"と出力)

'camel'という形は、EyeDrops.pmと同じディレクトリにある ファイルcamel.eyeであるということに注意してください。そのため 必要に合わせて、あなた独自の形を追加することもできます。

あなたのプログラムをわかりやすくする

あなたの上司があなたのプログラムを説明するUML図を指示したならば、 彼に、これを提出することが出来ます:

    print sightly( { Shape       => 'uml',
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

もし、それがWindowsプログラムであれば、図形を組み合わせる ことにより、それも示すことができます:

    print sightly( { Shape       => 'uml,window',
                     Gap         => 1,
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

これは改造された視覚的表現を生成します:

                ''=~('('.'?'.'{'.('`'|'%').('['^'-').(
                (                                    (
                (                                    (
                (                                    (
                (                                    (
                (                                    (
                '`'))))))))))|'!').('`'|',').'"'.('['^
                                  (
                                 ( (
                                (   (
                               '+'))))
                                  )
                                  )
                .('['^')').('`'|')').('`'|'.').(('[')^
                (                                    (
                (                                    (
 '/'))))).('{'^'[').'\\'.('"').(      '`'|'(').('`'|'%').('`'|"\,").(
 (                             (      (                             (
 (                             (      (                             (
 (                             (      (                             (
 (                             (      (                             (
 (                             (      (                             (
 '`'))))))))))))))))))))|"\,").(      '`'|'/').('{'^'[').('['^"\,").(

 '`'|'/').('['^')').('`'|',').('`'|'$').'\\'.'\\'
 .('`'|'.').'\\'.'"'.';'.('!'^'+').'"'.'}'."\)");
 $:='.'^'~';$~='@'|'(';$^=')'^'[';$/='`'|"\.";$_=
 "\("^                  ((                  '}'))
 ;($,)                  =(                  '`')|
 "\!";                  $\                  =')'^
 "\}";                  $:                  ='.'^
 "\~";                  $~                  ='@'|
 "\(";                  $^                  =')'^
 "\[";                  $/                  ='`'|
 "\.";                  $_                  ='('^
 "\}";                  $,                  ='`'|
 "\!";                  $\                  =')'^
 "\}";                  $:                  ='.'^
 '~';$~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('^'}';
 ($,)=                  ((                  '`'))
 |'!';                  $\                  =')'^
 "\}";                  $:                  ='.'^
 "\~";                  $~                  ='@'|
 "\(";                  $^                  =')'^
 "\[";                  $/                  ='`'|
 "\.";                  $_                  ='('^
 "\}";                  $,                  ='`'|
 "\!";                  $\                  =')'^
 "\}";                  $:                  ='.'^
 "\~";                  $~                  ='@'|
 '(';$^=')'^'[';$/='`'|'.';$_='('^'}';$,='`'|'!';
 $\=')'^'}';$:='.'^'~';$~='@'|'(';$^=')'^"\[";$/=
 '`'|'.';$_='('^'}';$,='`'|'!';$\=')'^'}';$:='.';

コードを一目見ただけで、それがWindowsプログラムであることが わかり、そのUML構造も見ることが出来る、これがビジュアル・ プログラミングによるブレークスルーなのです。

Linuxにのみ、その/usr/games/bannerコマンドを プログラムのソーステキストに適用することができます:

    print sightly( { Shape       => 'srcbanner',
                     Width       => 70,
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

その文字が大きく、読みやすくなるので、生成されたプログラムは 元のものよりも理解しやすくなります。

簡略化されたPerl6の歴史

これはこれまでのPerl6開発作業の概要です:

    print sightly( { Shape        => 'jon,larry,damian,simon,parrot',
                     Gap          => 3,
                     Regex        => 1,
                     Print        => 1,
                     SourceString => <<'END_HAIKU' } );
    Coffee mug shatters
    Larry Apocalyptic
    Parrot not a hoax
    END_HAIKU

生成されるもの:

                     ''=~(
                   '('."\?".
                  '{'.('['^'+'
                 ).('['^"\)").(
                 '`'|')').('`'|
                 '.').('['^'/').
                 '"'.('`'^'#').(
                 '`'|'/').(('`')|
                 '&').('`'|'&').(
                  '`'|'%').("\`"|
                  '%').('{'^'[').
                   ('`'|('-')).(
                     '['^"\.").(
                     '`'|"'").(
                    '{'^'[').('['^'(')
                   .('`'|'(').('`'|'!')
                   .('['^'/').('['^"\/").(
                   '`'|'%').('['^')').('['^"\(").(
                  '!'^'+').('`'^',').('`'|'!').('['^')').(
                 '['^')').('['^'"').('{'^'[').('`'^'!').('['^'+')
                .('`'|'/').('`'|'#').('`'|'!').('`'|',').('['^'"').
                ('['^'+').('['^'/').('`'|')').("\`"|        "\#").(
               '!'^'+').('{'^'+').('`'|('!')).(                 '['
               ^')').('['^')').('`'|"\/").(
               '['^'/').('{'^'[').('`'|'.')
               .('`'|'/').('['^'/').(('{')^
               '[').('`'|'!').('{'^'[').('`'
               |'(').('`'|'/').('`'|('!')).(
               '['^'#').('!'^'+').'"'.'}'.')'
               );$:='.'^'~';$~='@'|'(';$^=')'
               ^'[';$/='`'|'.';$_='('^'}';$,=
               '`'|'!';$\=')'^'}';$:='.'^'~';
               $~='@'|'(';$^=')'^'[';$/=('`')|
               '.';$_='('^'}';$,='`'|'!';$\=')'
      ^((      '}'));$:='.'^'~';$~='@'|"\(";$^=
 ')'^'[';$/    ='`'|'.';$_='('^'}';$,='`'|"\!";
 $\=')'^'}';$: ='.'^'~';$~='@'|'(';$^=')'^"\[";             $/
  ='`'|'.';$_='('^'}';$,='`'|'!';$\=')'^"\}";$:=           (  (
  '.'))^'~';$~='@'|'(';$^=')'^'[';$/='`'|('.');$_=         (  (
 '('))^'}';$,='`'|'!';$\=')'^'}';$:='.'^'~';$~="\@"|    '(';$^=
 ')'^'[';$/='`'|'.';$_='('^'}';$,='`'|'!';$\=')'^'}'; $:='.'^'~'
  ;$~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('^'}';$,='`'|'!';$\=')'^
   '}';$:='.'^'~';$~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('^"\}";$,=
    '`'|'!';$\=')'^'}';$:='.'^'~';$~='@'|'(';$^=')'^'[';$/='`'|"\.";
      $_='('^   "\}"; $,='`'|'!';$\=')'^'}';$:='.'^'~';$~='@'|'(';$^
                  =(  ')')^'[';$/='`'|'.';$_='('^'}';$,='`'|'!';$\=
                      ')'^'}';$:='.'^'~';$~='@'|'(';$^=')'^'[';$/=
                      '`'|'.';$_='('^'}';$,='`'|('!');$\=   "\)"^
                     '}';$:='.'^'~';$~='@'|'(';$^=')'^'[';
                     $/='`'|'.';$_='('^'}';$,='`'|('!');$\=
                    ')'^'}';$:='.'^'~';$~='@'|'(';$^=(')')^
                   '[';$/='`'|'.';$_='('^'}';$,='`'|"\!";$\=
                   ')'^'}';$:='.'^'~';$~='@'|'(';$^=')'^'[';
                  $/='`'|'.';$_='('^'}'  ;$,='`'|'!';$\="\)"^
                 '}';$:='.'^'~';$~='@'    |'(';$^=')'^'[';$/=
                '`'|'.';$_='('^'}';$,      ='`'|'!';$\=(')')^



                          '}';$:='.'^"\~";
                       $~='@'|'(';$^=')'^"\[";
                  $/='`'|'.';$_='('^'}';$,="\`"|
                "\!";                         ($\)
              =')'                              ^((
            '}')                                  );(
          $:)=                                   (  '.'
         )^((                                    (   '~'
        )));                                  $~  =    '@'
      |'('                                   ;     (    $^)
    =((                                    ((       ((   ')'
   )))                                   ))           )   ^((
  '['                                ));(              (   $/)
 )=(                             '`')                   |   '.'
 ;$_                         ='('                        ^   '}'
 ;$,                ='`'|'!';                            (   $\)
 =((              ((                                     (    ((
 ')'             ))                                       )   ))
 ))^            (                                         (   ((
 '}'            )                                          )));(
 $:)           =                                              ((
 '.'           )          )^'~';$~='@'|'(';$^=')'^'[';$/='`'|'.'
 ;$_           ='('^'}';$,=    '`'|'!'    ;    (   $\)=')'     ^
 '}'           ;          ( $:)  =((  ((  (    ( ((  '.'  )))  )
 )))           )          ^ '~';$~="\@"|  (    ( '('));$^=')'  ^
 '['           ;          (               (    (               (
 $/   )))     )           =               (    ((              (
 ((   (  '`'))            )               )     ))             )
 |+   (                   (               (     ( (            (
 ((   (  '.'               )))))))));($_)=       ( '(')^'}';$,=
 ((    (                              (          (          (
  (     (                            (          (           (
   (     (                            ( '`'    )            )
    )      )))                              ))             )
     )       )                  )))|'!';$\=')'^'}';$:      =
      (      (                '.'))^'~';$~='@'|'(';$^=     (
       (     (               ')')))^'[';$/='`'|"\.";$_=   (
        (   (                '('))  )^'}';$,="\`"|  '!';  (
         ( (                 $\))  )              =  ')' ^
          ((                 '}'   ));$:='.'^'~';$~   =((
           (                                            (
           (                                           (
           (                                          (
          (       (                                  (
          (        (                                (
          (          (                             (
          (            (                          (
         (               (                       (   (
         (                 (                    (     (
        (                    '@'              ))       )
       )                          )))))))))))            )



                   )))))))))))))|+
                 '(';$^=')'^('[');$/=
               '`'|'.';$_='('^'}';$,='`'
             |'!'                     ;$\=
           ')'^                         '}';
         ($:)                             ='.'
        ^'~'                                 ;$~=
       '@'|                                   '(';
      ($^)                                     =')'
     ^'['                                       ;$/=
    '`'|                                         '.'
    ;$_=                                         '('^
   '}';                                    $,='`' |'!'
   ;$\=                                ')'^     (  '}'
   );(    $:)                  ='.'^'~'          ;  $~=
  '@'     |  '(';           $^=                  (  ')'
 )^+      (      '[');$/='`'                     |  '.'
 ;$_      =                                      (  '('
 )^+      (                                      (  '}'
 ));      (                                       ( $,)
 )=(     (                                        ( '`'
  )))    |                                        ( '!'
  );     (                                        ( $\)
 ) =(    (                                        ( ((
 (  ((  (                                         ( ((
 (   ')')       )))))))))              )))^((     '}'
 )    );(    $:)         =((        '.'      ))^  '~'
 ; $~  =(        '@')|'('             ;$^=')'      ^+
 ( (   ((      ((  '[')  ))    )    )) ;$/=  ((    (
 ( (  '`'       )))))|'.';     (    $_)='('^'}'    ;
 (  (  $,                      )                  )
  =    ((                      (                 ((
  (    '`'                     )                 ))
   )   ))|                     (                '!'
    );($\)=                    (                ')'
      )^'}'              ;     (    (          $:)
      )='.'              ^     (    (          '~'
      ));$~=             '@'|"\(";$^=         ')'^
      '[';$/                                  ='`'
      |'.';$_         ='('^'}';$,='`'|'!'    ;$\=
       ')'^'}';    $:='.'^'~';$~='@'|'(';$^ =')'
        ^'[';$/=  ((                     "\`"))|
        '.';$_="\("^  '}';$,='`'|'!';$\=  (')')^
         '}';$:='.'      ^'~';$~="\@"|    "\(";
          $^=')'^'['                    ;($/)=
           '`'|('.');$_=            '('^"\}";
            $,='`'|'!';$\=')'^'}';$:='.'^'~'
            ;$~='@'|'(';$^=')'^'[';$/=('`')|
             '.';$_='('^'}';$,='`'|('!');$\=
              ')'^'}';$:='.'^'~';$~='@'|'(';
               $^=')'^'[';$/='`'|'.';$_='('
                 ^'}';$,='`'|'!';$\=(')')^
                  '}';$:='.'^'~';$~="\@"|
                    '(';$^=')'^('[');$/=
                      '`'|'.';$_=('(')^
                         '}';$,='`'|



                     '!';$\=')'^"\}";
                  $:='.'^'~'; $~=('@')|
                '(';$^=')'^'[' ;$/='`'|'.'
               ;$_='('^"\}";$,= '`'|"\!";$\=
             ')'^'}';$:='.'^'~' ;$~='@'|"\(";
           $^=')'^'[';$/='`'|'.' ;$_='('^"\}";
          $,='`'|'!';$\=')'^"\}"; $:='.'^'~';$~
         ='@'|'(';$^=')'^"\[";$/= '`'|'.';$_='('
        ^'}';$,='`'|'!';$\=')'^'}' ;$:='.'^'~';$~
       ='@'|'(';$^=')'^'[';$/='`'| '.';$_='('^'}';
      $,='`'|'!';$\=(')')^     '}' ;$:     ='.'^'~'
      ;$~='@'|'(';$^=')'                    ^'[';$/
     ='`'|'.';$_=('(')^                      '}';$,=
     '`'|'!';$\=')'^'}'                       ;($:)=
    '.'^'~';$~='@'|'(';                       $^=')'
    ^'[';$/='`'|'.';$_=                        "\("^
   '}';$,='`'|"\!";$\= (                       ')')
   ^'}';$:='.'^'~';$~  =                        '@'
   |'(';$^=')'^'[';$/  =                        ((
   '`'))|'.';$_="\("^  (                        ((
   '}')));$,='`'|'!'; (   ( ( (          (   (  (
   $\)))))))=')'^"\}"; (        (      (        (     (
   $:)))))='.'^'~';$~    ='@'|            '('  ;      (
 (   $^))=')'^'[';$/    ='`'|'.'         ;($_) =     (
   (  '('))^'}';$,                             =    (
     '`')|"\!";                      (          $\)
      =  ')'                         ^          (
      (                              (          (
      (                              (          (
       (    (                                   (
        ( ( (                   (     (  (      (
            (                  (      (  (      (
            (                  (      (  (
            (                                  (
         (   (
         (    (                   '}'))))))   )
         )     )             )))))))))))))
         )      )               ))))))))     ;
         (       (                 $:))='.'^'~';
         (         (           (                 (
         (             (     (                    (
          (                (                       (
                          (          (  (  (        (
           (                     (
                         (                           (
                              (                       (
                        (    (                         (
                            (                           (
                       ( ( (                             (



                                          $~)))))))
                                       ))))))))))))))
                                    ))))))))))='@'|"\(";
                                $^=')'^'[';$/='`'|'.';$_=
                              '('^'}';$,=('`')|   '!';$\=
                          ')'^'}';$:='.'^'~';$~   ='@'|'('
                      ;$^=')'^'[';$/='`'|'.';$_='('^'}';$,
                   ='`'|'!';$\=')'^'}';$:='.'^'~';$~="\@"|
                '(';$^=')'^'[';$/='`'|'.';$_='('^('}');$,=
              '`'|'!';$\=')'^'}';$:='.'^'~';$~='@'|'(';$^=
            ')'^'[';$/='`'|'.';$_='('^'}';$,='`'|"\!";$\=
           ')'^'}';$:='.'^'~';$~='@'|'(';$^=')'^     '['
          ;$/='`'|'.';$_='('^'}';$,='`'|'!';$\=    ')'
         ^'}';$:='.'^'~';$~='@'|'(';$^=')'^'['
        ;$/='`'|'.';$_='('^'}';$,='`'|'!';$\=
       ')'^'}';$:='.'^'~';$~='@'|'(';$^="\)"^
      '[';$/='`'|'.';$_='('^'}';$,='`'|"\!";
      $\=')'^'}';$:='.'^'~';$~='@'|('(');$^=
     ')'^'[';$/='`'|'.';$_='('^'}';$,="\`"|
     '!';$\=')'^'}';$:='.'^'~';$~='@'|'(';
    $^=')'^'[';$/='`'|'.';$_='('^"\}";$,=
    '`'|'!';$\=')'^'}';$:='.'^('~');$~=
   '@'|'(';$^=')'^'[';$/='`'|"\.";$_=
   '('^'}';$,='`'|'!';$\=')'^"\}";$:=
  '.'^'~';$~='@'|'(';$^=')'^('[');$/=
  '`'|'.';$_='('^'}';$,='`'|"\!";$\=
 ')'^'}';$:='.'^'~';$~='@'|('(');$^=
 ')'^'[';$/='`'|'.';$_='('^"\}";$,=
 '`'|'!';$\=')'^'}';$:='.'^"\~";$~= '@'
 |'(';$^=')'^'[';$/='`'|'.';$_='('^     (
 '}');$,='`'|'!';$\=')'^('}');$:=     '.'^
 '~';$~='@'|'(';$^=')'^('[');$/=    '`'|'.'
 ;$_='('^'}';$,='`'|'!';$\=')'^   '}';$:='.'^
 '~';$~='@'|'(';$^=')'^'[';$/=   '`'|'.';$_='('
 ^'}';$,='`'|"\!";$\=       ((  ')'))^'}';$:='.'^
 '~';$~='@'|('(');$^=        (  ')')^'[';$/='`'|'.'
 ;$_='('^'}';$,="\`"|         ( ( '!'));$\=')'^'}';
 $:='.'^'~';$~='@'|'('         ;     $^=')'^'[';$/=
 '`'|'.';$_='('^'}';$,                  ='`'|"\!";
 ($\)  =')'^'}';$:='.'                     ^'~';$~
 =((   '@'))|('(');$^=                        ')'
 ^+    '[';$/='`'|"\.";
 (     $_)='('^"\}";$,=
       '`'|'!';$\="\)"^
       '}';$:='.'^"\~";

もしあなたが心からLarryを偶像視するのであれば、彼の周りに 枠をつけるかもしれません:

    print sightly( { Shape       => 'larry2',
                     BorderGap   => 3,
                     BorderWidth => 2,
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

larry2という形は、Ryan Kingにより寄稿されたマンガです:

 ''=~('('.'?'.'{'.('`'|'%').('['^'-').('`'|'!').("\`"|
 ',').'"'.('['^'+').('['^')').('`'|')').('`'|'.').('['
 ^+                                                 ((
 ((                                                 ((
 ((                                                 ((
 ((                 '/')))))))))))                  ))
 .(             '{'^'[').'\\'.'"'.('`'              |+
 ((            '('))).('`'|'%').('`'|','            ).
 +(          '`'|(',')).( '`'|'/'). ('{'^           ((
 ((         '['))))).('['  ^',').(  ((  '`'         ))
 |+        '/' ).('['^')') .("\`"|  (    ','        ))
 .(       '`' |"\$").'\\'.  '\\'.  (      '`'       |+
 ((       '.' ))).('\\').   '"'.  (        ((       ((
 ((      ';') )))))).''.   ('!'             ^       ((
 ((     '+'))) )). '"'    . (             ((        ((
 ((    '}')))))) )      . (    (    (     ((        ((
 ((    ')')))))) ))));    $:='.'^'~';$~=('@')|      ((
 ((    '(')))); $^  ="\)"^      (( ((    (  ((      ((
 ((     '[')))))     )))         ) )     )   ;(     $/
 )=    '`'|'.';       $_       = ( ( (    (  ((     ((
 ((     '('))))       ))         ) )      )  )^     ((
 ((      '}')))        );       $,  =(     '`'      )|
 ((       "\!"));  (    $\)=')'^     '}'; $:        =(
 ((        '.')))^ (        '~'); ($~)= ( ((        ((
 ((         '@'))))))      )|"\(";  $^=')'^'['      ;(
 $/           )="\`"|   '.';$_='('   ^'}';$,='`'    |+
 ((            '!')) ; $\=(')')^        (  "\}");   $:
 =(                (  '.'))      ^'~'     ;  ($~)   =(
 ((              ( (   '@'               )    )))   )|
 ((           '(' )    );  (            (     $^    ))
 =(         ((  (       (    "\)")))))^       (     ((
 ((      '['     ))           )                     ))
 ;(     (         $/           ))                   =(
 ((   (             ((        (   (                 ((
 ((                   '`')))))     )                ))
 ))                                                 ))
 |+                                                 ((
 ((                                                 ((
 '.'))))));$_='('^'}';$,='`'|'!';$\=')'^'}';$:='.'^'~'
 ;$~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('^'}';$,="\`";

Just another Perl hacker

より意欲的にして、大きく自分自身を出力するJAPHを作ってみましょう。

    my $src = <<'FLAMING_OSTRICHES';
    open 0;
    $/ = undef;
    $x = <0>;
    close 0;
    $x =~ tr/!-~/#/;
    print $x;
    FLAMING_OSTRICHES
    print sightly( { Shape         => 'japh',
                     SourceString  => $src,
                     Regex         => 1 } );

これは動きます。しかし以下のものを:

    $x =~ tr/!-~/#/;

を以下のように変更すると:

    $x =~ s/\S/#/g;

生成されたプログラムは奇妙な動きをして、うまく動きません。というのも それが正規表現の内側で走り、Perlの正規表現エンジンが再入可能(reentrant) ではないからです。この場合、以下のようにして逃げなければなりません:

    print sightly( { Shape        => 'japh',
                     SourceString => $src,
                     Regex        => 0 } );

これは生成された見た目の良いプログラムを代わりにevalを通して実行します。 Regex => 1を使いたいのであれば、変換されるプログラムが、正規表現と$_の 使い方に注意していることを確実にしてください。

元のJust another Perl hacker,、別名Randal L Schwartzに似ている JAPHを生成するためには、以下のようにしてください:

    print sightly( { Shape        => 'merlyn',
                     SourceString => 'Just another Perl hacker,',
                     Regex        => 1,
                     Print        => 1 } );

生成されるもの:

                       ''=~('('.'?'.'{'.('['
                    ^'+').('['^')').('`'|')').(
                 '`'|'.').('['^'/').'"'.('`'^'*')
              .('['                          ^'.')
            .('['                              ^'(')
           .('['                                ^'/')
         .('{'^                                 '[').(
        "\`"|                                    '!').(
       '`'|                                      '.').(
      '`'|          (                (           '/'))).
    ('['            ^              ( (          '/'))).(
   '`'|           (              (  (         ( '('))))).
  ('`'|         (              (    (        (  '%'))))).
  ('['^       (              (    (        (    ')'))))).
  ('{'^      '[')        .(      (      ((      ('{'))))^
  '+').     (    '`'|'%'       ).("\["^         ')').('`'
 |',').('{'^                                    '[').('`'
 |'(').('`'                                      |"\!").(
 '`'|'#').(        ('`')|             '+').(     '`'|'%')
 .('['^')')     .((      ','       )).      '"'   .('}').
 "\)");$:=         ('.')^       (     "\~");      $~='@'|
 ('(');$^=       (( ')'  ))     ^   (( '['  ))     ;($/)=
  '`'|'.';       $_='('^'}'     ;   $,='`'|'!'      ;($\)
  =(')')^                       (                    '}'
   );($:)                       =                    '.'
    ^'~';                     ( ( (                  $~)
    )  )=                    (  (  (                 '@'
    )   )                   ) | ( ( (               '('
    )   )                   ) ; ( ( (               $^
    )   )                                          ) =
     (  (                                         ( (
      ( (                                         ( (
       (               ')')))))))))^'['     ;    # ;
        #        ;    #                ;    #    ;#
        ;        #     ;              #    ;    #;
        #        ;      #;          #;    #    ;
        #        ;        #       ;#      ;   #
        ;        #          ;#;#;        #   ;
         #        ;                     #   ;
         #        ;                    #   ;
          #        ;                      #
           ;       #                     ;
            #      ;                    #
             ;      #                  ;
              #                      ;
                #                  ;
                  #;#           ;#
                      ;#;#;#;#;

鏡で見るBuffy

見た目のよいエンコードはコンパクトではないため、あなたは時折、 Perl Golfの超現実的な形式を楽しんでいることがわかるかもしれません。 そこでの勝者は以下のような最も小さいf.tmpを持ったものです:

    sightly.pl -r -f program_to_be_converted >f.tmp

(キー)ストロークの数を減らすことを別にすれば、正規表現を避け、 英数字を見た目のよいもので置き換えるべきです。それは見た目のよい エンコーディングを必要としません。

説明するために、鏡で見るBuffy(=Buffy looking in the mirror)を 作成する、面白い問題を考えてみましょう。k.plから始めましょう:

    open$[;chop,($==y===c)>$-&&($-=$=)for@:=<0>;
    print$"x-(y---c-$-).reverse.$/for@:

EyeDropsが生成するプログラムには後ろに空白が入っていないことに 注意してください。それが、上記のプログラムをおかしくします。

鏡で見るBuffyは、これで以下のように作成することができます:

    sightly.pl -r -f k.pl -s buffy2 >b.pl
    cat b.pl        (Buffyの顔を表示します)
    perl b.pl       (鏡で見るBuffyを表示します)

チィッ。これはbuffy2の図形を2つ必要とします。何をするべきでしょうか? あなたは必要とされる数の空白を追加するため、各行に追加するための ポスト・プロセッサ・プログラム、ここではpp.plを 書く事が出来ます:

    chop,$==y===c,$=<$-or$-=$=for@a=<>;
    print$_.($"x($--length)).$/for@a

このプログラムがあれば、kk.plをより短く書く事が出来ます:

    open$%;chop,print+reverse.$/for<0>

そして最後に、以下のようにして鏡で見るBuffy を生成します:

    sightly.pl -r -f kk.pl -s buffy2 >b.pl
    perl pp.pl b.pl >bb.pl

この例では、しかしながら、Compact 属性(sightly.plでは-m スイッチ)が、後ろの空白を必要とすることなく、より直接的な解決方法を 提供します:

    sightly.pl -mr -f k.pl -s buffy2 >buffy.pl
    cat buffy.pl     (Buffyの顔を表示)
    perl buffy.pl    (鏡で見たBuffyを表示)

生成される buffy.pl:

                    ''=~('(?{'.(
                 '`'|'%').('['^'-'
               ).('`'|'!').('`'|','
              ).+               ( '"'
             ).(                (  '`'
            )|+                 (   '/'
           )).                  (   '['
          ^((                  (     '+'
         )))              ).('`'      |((
         '%'          ))).      (     '`'
        |((       '.')           )     ).+
        (((     ((                (     (((
        (((    (                   (    (((
        (((   (                     '\\')))
       )))    )                      ) )  )
       )   )))) ))))))      .'$[;'     .  (
       (  (  ((                        (  (
       (  (      ( (( (     ( (( (     (   (
       (  (       '`')       ))))      )   )
       )   )                        )))    )
       )    )))                     )      )
       )|      (       (   (        (     ((
       '#'      )        )          )    )))
        ).(('`')|                   ('(')).(
        '`'|'/').    ('['^'+')     .',(\\$'
        .'=='.('['     ^'"')     . '==='.+(
        '`'|'#').')'            .  '>\\$-'
        .'&&(\\$-=\\'          .   '$=)'.(
        '`'|'&').('`' |      (     '/')).(
        '['^')').'\\'     .        '@:=<' .
        ('^'^(('`')|              "\.")).   (
        '>').(';').(              '!'^'+'     )
         .('['^'+').             ('['^')'     ).('`'|
         ')').("\`"|             "\.").(      (      ('['))^
   "\/").'\\$\\"'.(            ( "\[")^       (             (
  (    ( "\#"))))). (        (   '-'))        .              (
 (     ( ('(')))).(   (   (     '['))         ^              (
 (     '"'))).'--'       .     '-'.           (              (
 (    '`'))|'#').        (                    (               (
 (     '-')))).          (                    (               (
 (     ( '\\'                                 )               )
 )     )                                      )               .
 (     (                                      (               (
 (     (                                      (      (         (
 (     (                                      (      (         (
 (     (                                      (     (          (
 (     (                                      (     (          (
 (     '$'))))))))))))))))))))))))).'-).'.('['^    (           (
 (    ')')))).('`'|'%').('['^'-').('`'|'%').(('[')^            (
 (    ')'))).('['^'(').('`'|'%').'.\\$/'.('`'|'&').(           (
 (   '`'))|'/').('['^')').'\\@:'.('!'^'+').'"})');$:=          (
 (   '.'))^'~';$~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('         ;

しかし人によっては目に、プレインな見た目のよいエンコーディングの ほうが楽しいと思うかもしれませんが、これはおそらくよりキレイな 解決法でしょう。

面白いことに、鏡像ではなく、顔を上下逆さまに表示することは、 以下の様にして、より簡単に解決されます:

    open$%;print+reverse<0>

そして自分自身を表示したり:

    open$%;print<0>

あるいは空白以外を'#'で置き換えて自分を表示することも簡単です:

    open$%;print+map{y;!-~;#;;$_}<0>

ラクダの宙返り

前の章のBuffyの例を、実行したときに画面を宙返りするような能力を持った ラクダの形をしたプログラムを生成するように拡張しましょう。

生成するプログラム、gencamel.plから始めます:

    use Acme::EyeDrops qw(sightly);
    my $src = <<'END_SRC_STR';
    $~=pop||'';open$%;
    y,!-~,#,,s,(.).,$+,gs,$~&&($_=reverse)for@~=grep$|--,('')x18,<0>;
    @;=map~~reverse,reverse@~;
    map{system$^O=~Win?CLS:'clear';
    ($-=$_%3)||(--$|,map$_=reverse,@~,@;);
    print$"x($=/3*abs$|*2-$-),$_,$/for$-&1?@;:@~;
    sleep!$%}$%..11
    END_SRC_STR
    $src =~ tr/\n//d;
    my $prog = sightly( { Regex         => 1,
                          Compact       => 1,
                          Shape         => 'camel',
                          SourceString  => $src } );
    my @a = split(/\n/, $prog);
    my $max = 0; length > $max and $max = length for @a;
    $_ .= ' ' x ($max - length) for @a;
    print " $_ \n" for @a;

Compact属性の使い方について注意してください。ここでの必要なのは 上記のプログラムを1つのラクダの形に絞るためです。

これを実行すると:

    perl gencamel.pl >camel.pl

camel.plを生成します:

                                       ''=~('(?{'.(                
            ('`')|                   '%').('['^'-').               
         ('`'|'!').                ('`'|',').'"\\$~='              
  .('['^'+')  .('`'|              '/').('['^'+').'||'.             
 "'"."'".';'.('`'|'/'            ).('['^'+').('`'|'%').            
 ('`'|'.').('\\$%;').(          '['^'"').(',!-~,#,,').(            
   '['^'(').',(.).,\\'        .'$+,'.('`'|"'").('['^'(')           
        .',\\$~&&(\\$'      .'_='.('['^')').('`'|('%')).(          
       '['^'-').('`'|     '%').('['^')').('['^'(').(('`')|         
      '%').')'.("\`"|   '&').('`'|'/').('['^"\)").'\\@~='.(        
     '`'|"'").("\["^   ')').('`'|'%').('['^'+').('\\$|--,(').      
     "'"."'".(')').(  '['^'#').('^'^('`'|'/')).(':'&'=').',<'.     
     ('^'^('`'|'.')  ).'>;\\@;='.('`'|'-').('`'|'!').('['^'+')     
     .'~~'.('['^')'  ).('`'|'%').('['^'-').('`'|'%').('['^')').    
     ('['^'(').('`'|'%').','.('['^')').('`'|'%').('['^'-').('`'    
     |'%').('['^')').('['^'(').('`'|'%').'\\@~;'.('`'|'-').('`'|   
      '!').('['^'+').'\\{'.('['^'(').('['^'"').('['^'(').(('[')^   
      '/').('`'|'%').('`'|'-').'\\$^'.('`'^'/').'=~'.('{'^"\,").(  
       '`'|')').('`'|'.').'?'.('`'^'#').('`'^',').('{'^'(').(':'). 
        "'".('`'|'#').('`'|',').('`'|'%').('`'|'!').('['^')')."'". 
         ';(\\$-=\\$_%'.('^'^('`'|'-')).')||(--\\$|,'.('`'|'-' ).( 
          '`'|'!').('['^'+').'\\$_='.('['^')').('`'|'%').('['  ^(( 
           '-'))).('`'|'%').('['^')').('['^'(').('`' |('%')).  ',' 
             .'\\@~,\\@;);'.('['^'+').('['^(')')).(  '`'|')'   ).( 
              "\`"| '.').('['^'/').'\\$\\"'.("\["^   ('#')).   '(' 
                    .'\\$=/'.('^'^('`'|'-')).'*'.    (('`')|   '!' 
                    ).("\`"|    '"').('['^ "\(").     '\\$|'   .+  
                    ('*').(     '^'^('`'   |','))     .'-\\'  .+   
                    '$-),'.     '\\$_,'.   '\\$'       .'/'.  (    
                    ('`')|      ('&')).(   '`'|         '/')       
                    .('['^     ')').'\\'   .'$'         .'-'       
                     .'&'.     (('^')^(    '`'|         '/')       
                     ).'?'     .'\\@;'     .':'         .''.       
                     '\\'     .'@~;'       .''.         ('['       
                     ^'('     ).(          '`'|         ',')       
                     .''.      (((         '`'          ))|        
                     '%'        ).(       '`'           |((        
                     '%'         )))     .+(            '['        
                     ^((          '+'   )))              .+        
                     ((             '!')).               ((        
                     ((              '\\')               ))        
                     ).             '$%\\}'.             ((        
                    (((            '\\' )))))            .+        
                   '$'           .'%..'  .''.           (((        
                  '^')         )^("\`"|   '/'          )).(        
                "\^"^(                                ('`')|       
              ('/'))).                               '"})');       

注意: Perlに関連付けてラクダの画像を使用することは O'Reilly & Associates, Inc.の商標です。許可を受けて使用しています

以下の様にしてcamel.plを実行することができます:

    perl camel.pl           通常の方向に宙返りするラクダ
    perl camel.pl b         後ろの方向に宙返りするラクダ
    perl camel.pl please do a backward somersault
                            同じこと

そのヘッダ行の後に空行も追加する限り、camel.plの先頭に #!/usr/bin/perl -wという行を入れてもかまいません。

12,032種類のラクダ

上記の宙返りするラクダと似た方法で、実行したとき12,032種類の異なる ラクダを吐き出す、ラクダの形をしたプログラムを作成します。

いつものように、生成するプログラムgencamel.plから始めます:

    use Acme::EyeDrops qw(sightly);
    my $src = <<'END_SRC_STR';
    $~=uc shift;$:=pop||'#';open$%;chop(@~=<0>);$~=~R&&
    (@~=map{$-=$_+$_;join'',map/.{$-}(.)/,@~}$%..33);
    $|--&$~=~H&&next,$~!~Q&&eval"y, ,\Q$:\E,c",$~=~I&&
    eval"y, \Q$:\E,\Q$:\E ,",$~=~M&&($_=reverse),
    print$~=~V?/(.).?/g:$_,$/for$~=~U?reverse@~:@~
    END_SRC_STR
    $src =~ tr/\n//d;
    my $prog = sightly( { Regex         => 1,
                          Compact       => 1,
                          Shape         => 'camel',
                          SourceString  => $src } );
    my @a = split(/\n/, $prog);
    my $max = 0; length > $max and $max = length for @a;
    $_ .= ' ' x ($max - length) for @a; $\ = "\n";
    print ' ' x ($max+2); print " $_ " for @a; print ' ' x ($max+2);

これを実行し:

    perl gencamel.pl >camel.pl

camel.plを生成します。これは以下の様に実行することができます:

    perl camel.pl           通常のラクダ
    perl camel.pl q         quine (プログラムがそれ自身を出力)
    perl camel.pl m         鏡像 (鏡で見るラクダ)
    perl camel.pl i         反転したラクダ
    perl camel.pl u         上下逆さまのラクダ
    perl camel.pl r         回転したラクダ
    perl camel.pl h         水平方向につぶれたラクダ
    perl camel.pl v         垂直方向につぶれたラクダ

そしてさらに上記のオプションと組み合わせることができます。 それぞれの組み合わせは異なるラクダを生成します。例えば:

    perl camel.pl uri

は、大きな、あごひげを蓄え、ポニーテールで、メガネをかけ、 絞り染めのTシャツを着たラクダを生成します。 :)

camel.plはオプションで、ラクダを埋める文字を指定する、 第2の引数を受け取ることが出来ます。(デフォルトは#)。 例えば:

    perl camel.pl hv        #で埋められた小さなラクダ
    perl camel.pl hv "$"    $で埋められた小さなラクダ

なぜ12,032種類のラクダなんでしょうか?主たるオプションq, m, i, u, r, h, vは 128の異なるラクダを生成します。そして第2パラメータとして94の出力可能な 文字が利用できます。合計を求めると 128 * 94 = 12,032種類のラクダになります。

裸で腕相撲

ミュンヘン(Munich)でのY::E 2002での最後のオークションは大叙事詩的な 運動競技が呼び物でした。これを以下のようにして思い出すことができます:

    print sightly( { Regex         => 1,
                     Shape         => 'naw',
                     Indent        => 1,
                     SourceString  => <<'NAKED_ARM_WRESTLING' } );
    $/='';open$%;$x=<0>;$y=<0>;
    substr($y,428,$%)='     AAAAARRRGGGHHH!!!';
    map{system$^O=~Win?CLS:'clear';
    print$_&1?$y:$x;sleep!$%+($_&1)}$%..9
    NAKED_ARM_WRESTLING

シェルピンスキーの三角形

シェルピンスキーの三角形(=Sierpinski triangle)を生成するプログラムは さまざまなメーリングリストやPerl monksでも人気を証明してきました。

単純で簡潔なシェルピンスキーの三角形を生成するプログラム、siertri.plは 以下の通りです:

    #!perl -l
    $x=2**pop;print$"x--$x,map$x&$_?$"x2:"/\\",0..$y++while$x

これはMtv Europeにより、元のAdam Antonikのプログラムをワン・ストローク 改善したものとして、golf@perl.orgへ14-sep-2002に投稿されました。 これを実行すると:

    perl siertri.pl 4

2**4行のシェルピンスキーの三角形を表示します。

(Acme::EyeDrops 1.13で)Mtvのプログラムが最も短いと示すことは、 以下のいくつかのようにハードに$^Fを利用することによって、より短くするよう、 Adam Antonik と Eugene van der Pijllを刺激しただけでした:

    -l print$"x--$x,map$x&$_?$"x2:"/\\",0..$_-1for 1..($x=2**pop)
    -l $x=2**pop;print$"x--$x,map$x&$_?$"x2:"/\\",0..$y++while$x
    -l $^F**=pop;print$"x--$^F,map$^F&$_?$"x2:"/\\",0..$y++while$^F
    -lX061 print$"x--$/,map$/&$_?$"x2:"/\\",0..$y++while$/<<=pop
    -l print$"x--$^F,map$^F&$_?$"x2:"/\\",0..$y++while$^F*=2**pop
    -l $_=$"x2**pop;$_="$'/\\",print,s/(?<=\\)../$&^KI^D5/egwhile/^ /

シェルピンスキーの三角形を作成する面白く判りにくいプログラムは:

    #!/usr/bin/perl -l
    s--@{[(gE^Ge)=~/[^g^e]/g]}[g^e]x((!!+~~g^e^g^e)<<pop).!gE-ge,
    s-[^ge^ge]-s,,,,s,@{[(g^';').(e^'?')]},(G^'/').(E^'|')^Ge,ge,
    print,s,(?<=/[^g^e])[^g^e][^g^e],$&^(G^'/').(E^'|')^gE,ge-ge

もう一つのわかりにくいものとしては、以下のようなMtvのプログラムを ベースとした、シェルピンスキーの三角形を作成するシェルピンスキーの 三角形の形をしたプログラムです:

    use Acme::EyeDrops qw(sightly);
    my $src = <<'END_SRC';
    $-=!$%<<(pop||4);print$"x$-,map($-&$_?'  ':'/\\',$%..$.++),$/while$---
    END_SRC
    $src =~ tr/\n//d;
    print sightly( { SourceString    => $src,
                     Regex           => 1,
                     Compact         => 1,
                     Indent          => 1,
                     BorderGap       => 1,
                     BorderWidth     => 2,
                     # For 'siertri' built-in shape, Width=>5 means:
                     #   height is 2**5 lines
                     #   width  is 2 * 2**5 characters
                     Width           => 5,
                     Shape           => 'siertri' } );

生成されるもの:

 ''=~('(?{'.('`'|'%').('['^'-').('`'|'!').('`'|"\,").'"\\$-=!\\$%<<('.(
 '['^'+').('`'|'/').('['^'+').'||'.('^'^('`'|'*')).');'.('['^'+').('['^
 ((                                                                  ((
 ((                                ((                                ((
 ((                               ')')                               ))
 ))                              ))  ))                              ))
 ))                             .(('`')|                             ((
 ((                            ((      ((                            ((
 ((                           ')')    ))))                           ))
 ))                          ))  ))  .(  ((                          ((
 ((                         '`'))))))|'.').(                         ((
 ((                        ((              ((                        ((
 ((                       '[')            ))))                       ))
 ))                      ))  )^          ((  ((                      ((
 ((                     '/')))))        )))).''.                     ((
 ((                    ((      ((      ((      ((                    ((
 ((                   '\\'    ))))    ))))    ))))                   ))
 ))                  .+  ((  ((  ((  ((  ((  ((  ((                  ((
 ((                 '$')))))))))))))))))).'\\"'.('['                 ^+
 ((                ((                              ((                ((
 ((               '#')                            ))))               ))
 ))              ))  .+                          ((  ((              ((
 ((             '\\'))))                        )))).'$'             .+
 ((            ((      ((                      ((      ((            ((
 ((           '-')    ))))                    ))))    ))))           ).
 ((          ((  ((  ((  ((                  ((  ((  ((  ((          ((
 ((         ',')))))))))))))                ))))))))).("\`"|         ((
 ((        ((              ((              ((              ((        ((
 ((       '-')            ))))            ))))            ))))       ))
 ))      .(  ((          ((  ((          ((  ((          ((  ((      ((
 ((     '`')))))        ))))))))        )))))|((        '!'))).(     ((
 ((    ((      ((      ((      ((      ((      ((      ((      ((    ((
 ((   '[')    ))))    ))))    ))))    ))))    ))))    )))^    '+')   .+
 ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((  ((
 (( '(')))))))))))))))))))))))))))))))))))))).'\\$-&\\$_?'."'".('{'^ ((
 ((                                                                  ((
 '['))))))).('{'^'[')."'".':'."'".'/\\\\\\\\'."'".',\\$%..\\$.++),\\$/'
 .('['^',').('`'|'(').('`'|')').('`'|',').('`'|'%').'\\$---"})');$:='.'

闘うディンゴ(Dueling Dingos)

TPR02 Perlゴルフ・トーナメントの間に、`/anickは彼の経験について 述べたDueling Dingosという詩を書きました。

彼の動く詩を書き出すプログラムを以下のように作ることが出来ます:

    print sightly( { Shape        => 'yanick3',
                     Regex        => 1,
                     Print        => 1,
                     SourceString => <<'END_DINGO' } );
    #!/usr/bin/perl
    # Dueling Dingos v1.1, by Yanick Champoux (9/4/2002)
    #
    # Inspired by the TPR(0,2) Perl Golf contest.
    # Name haven't been changed, since the involved
    # parties could hardly be labelled as 'innocent',
    # and are way far too gone to protect anyway.

    wait until localtime > @April[0];  # wait until the first of April

    BEGIN{}

    study and seek FOR, $some, $inspiration;

    write $stuff;

    $score = 145; # no good;

    delete $stuff { I_can_do_without }
       and do $more_stuff;

    delete $even{more_stuff};

    reverse $engineer; study; eval $strategy and redo;

    write, write, write;
    delete $_{'!'}, delete $"{"@!"}, delete $@{'*'}; # must stop cursing

    use less 'characters', $durnit;

    read THE, $current, $solution;

    not 2, $bad;

    delete $white_spaces{''} until $program == glob;

    for( $all, my @troubles )
    {
        unlink 1, $character;
    }

    ARGH:

    $must, not $despair;

    $I->can(do{ $it });

    study new Idea;

    m/mmmm/m... do{able};

    kill $chickens;

    'ask', $Nanabozo, 2, bless $me, 'with more inspiration';

    $so, close; warn $mailing_list and alarm $Andrew;

    $toil until my $solution < /-\ndrew's
    /;

    GOT_IT:

    send $solution, $to, ref;

    $brain, shutdown  I,'m dead';

    goto sleep;

    wait; $till, $the, $day, $after;

    readline last $scoreboard;

    grep $all, stat;

    read THE, $stats, $again until $it_sinks_in;

    $Andrew,'s score' lt $mine;

    $eyeball, pop @o
    ;
    END_DINGO

ここでは、生成される2577行ものプログラムは再び生成されません。 `/anickのTPR02での苦悩をまとめる、より短いプログラムを生成するためには 以下のようにします:

    print sightly( { Shape        => 'yanick,eye,mosquito,coffee',
                     Gap          => 3,
                     Regex        => 1,
                     Print        => 1,
                     SourceString => <<'END_SUFFERING' } );
    My head is hurting, my right eye feels like it's going to pop
    like a mosquito drinking from an expresso addict with high
    blood pressure, I want to crawl somewhere damp and dark and
    quiet and I consider never to touch a keyboard again.
    END_SUFFERING

生成されるもの:

                             ''=~('('.'?'.'{'.(
                          '['^'+').('['^')').('`'|
                        ')').('`'|'.').('['^'/').'"'
                      .('`'^'-').('['^'"').('{'^'[').(
                     '`'|'(').('`'|'%').('`'|'!').("\`"|
                    '$').('{'^'[').('`'|')').('['^('(')).(
                   '{'^'[').('`'|'(').('['^'.').('['^"\)").(
                  '['^'/').('`'|')').('`'|'.').('`'|"'").','.
                 ('{'^'[').('`'|'-').('['^'"').('{'^'[').('['^
                 ')').('`'|')').('`'|"'").('`'|'(').('['^'/').(
                '{'^'[').('`'|'%').('['^'"').('`'|'%').('{'^'['
               ).('`'|'&').('`'|'%').('`'|'%').('`'|',').(('[')^
              '(').('{'^'[').('`'|',').('`'|')').('`'|'+').("\`"|
             '%').('{'^'[').('`'|')').           ('['^    ('/')).
            "'".('['^'(').('{'^'[').                       ("\`"|
            "'").('`'|'/').('`'|')'                         ).''.
           ('`'|'.').('`'|"'").('{'                         ^'[')
     .('[' ^'/').('`'|'/').(('{')^                          '[').
  ('['^'+'  ).('`'|'/').('['^'+').                          ('!'^
 '+').('`'  |',')  .('`'|(')')).(                           "\`"|
 '+').('`'  |'%'    ).('{'^'[').                            ('`'|
 '!').('{'     ^      ('[')).(                              "\`"|
 '-').('`'     |      "\/").(                               "\["^
 '(').('['     ^       '*'                                   ).(
 '['^'.'       )     .+(             (  ( (            ( (    (
 '`')))        )   ))                         |      (        (
 ')'))         )                   .               (         (
 '[')^         (                                            (
 '/'))         )                      .('`'|        '/').  (
 "\{"^          '['                   ).('`'        |'$') .
 ('['^           (                                (      (
 ')'))            )                               )     .
 ('`'|            (                  ')'))        .     (
 "\`"|             (            '.'))              .   (
 "\`"|              (                               ( (
 '+')))              )           .(         (       (
 "\`"))|              (           ((         (       (
 ')'))))))             .           +(         (     (
 '`'))|'.').(           (           ((          ( (
 '`')))))|"'").('{'^'[').(            ((         (
 '`')))|'&').('['^')').('`'|            ((     (
 '/')))).('`'|'-').('{'^'[').             ('`'
 |'!').('`'|'.').('{'^'[').('`'             |
 '%').('['^'#').('['^'+').("\["^          (
 ')')).('`'|'%').('['^('(')).(     '['^'('
 ).('`'|'/').('{'^'[').("\`"|
 '!').('`'|'$').('`'|"\$").(



                          '`'|')').(('`')|
                    (  '#')).('['^'/').("\{"^  (
                (    '['))).('['^',').('`'|')')    .
             (     '['^'/').('`'|'(').('{'^'[').(     (
          (       '`'))|'(').('`'|')').('`'|"'").(       (
        (        '`'))|'(').('!'^'+').('`'|('"')).(        (
      (          '`'))|',').('`'|'/').('`'|('/')).(          (
    (           '`'))|'$').('{'^'[').('['^'+').('['^           (
  (             ')'))).('`'|'%').('['^'(').('['^'(')             .
 (              '['^'.').('['^')').('`'|'%').(',').(              (
  (             '{'))^'[').('`'^')').('{'^'[').('['^             (
    (           ','))).('`'|'!').('`'|'.').('['^'/')           .
      (          '{'^'[').('['^'/').('`'|'/').('{'^          (
        (        '['))).('`'|'#').('['^')').(('`')|        (
          (       '!'))).('['^',').('`'|',').('{'^       (
             (     '['))).('['^'(').('`'|('/')).(     (
                (    '`'))|'-').('`'|'%').('['^    (
                    (  ','))).('`'|'(').('`'|  (
                          '%')).('['^')').



              +(                                                 ((
             '`'))                                             |  (
            "\%")).(                                         (   (
            '{'))^'['                 )  .                 (   (
            '`')|'$').(               (  (               (   (
            '`'))))|'!')              .  (            (   (
             '`'))|'-').(             (  (          (   (
              '['))))^'+')            .  (        (    (
               '{'))^'[').(           (  (     (    (
                 '`'))))|'!'          ) .   (     (
    '`')|'.'       ).('`'|'$'         ) .  (  (
 '{')^'[').('`'|      ('$')).(  '`'| '!' )  .
 ('['^')').('`'|'+')     .('{'^'[').('`'| (
  '!')).('`'|'.').('`'|'$').('!'^"\+").( (
   '[')^'*').('['^'.').('`'|')').('`'|'%'
    ).('['^'/').('{'^'[')   .('`'|'!').
      ('`'|('.')).(       '`'|('$')).(
                             '{'^'['
                            ).( '`'
                           ^+ ( ( (
                           (( ( ( (
                          (( ( (  (
                         (( (  (  (
                        ((  ( (   (
                     ')')  )  )   )
                      )) ) )  )   )
                         ) )  )   )
                         ) )  )  )
                         ) ) )   )
                        )  ) .   (
                        (  ( (  (
                        (  ( (  (
                        (  ( ( (
                        ( ( (  (
                        '{'))))
                        ))))))
                        )))))
                       )^'['
                      ).''.
                     ('`'|



 '#').('`'|'/').('`'|'.').('['^'(').(('`')|   ')').(
 '`'|'$').('`'|'%').('['^')').('{'^('[')).( '`'|'.').
 ('`'|'%').('['^'-').('`'|'%').('['^')').('{'^    '['
 ).('['^'/').('`'|'/').('{'^'[').('['^'/').(      '`'
 |'/').('['^'.').('`'|'#').('`'|'(').("\{"^       '['
  ).('`'|'!').('{'^'[').('`'|'+').('`'|'%'       ).(
  '['^'"').('`'|'"').('`'|'/').('`'|'!').(     '['^
   ')').('`'|'$').('{'^'[').('`'|('!')).(    '`'|
    "'").('`'|'!').('`'|')').('`'|"\.").   '.'.
     ('!'^'+').'"'.'}'.')');$:='.'^('~');$~=
      '@'|'(';$^=')'^'[';$/='`'|'.';$_='('
        ^'}';$,='`'|'!';$\=')'^'}';$:=
          '.'^'~';$~='@'|('(');$^=
            ')'^'[';$/='`'|'.'

バイナリ・ファイルのエンコーディング

ちょっと待ってください、まだまだあるんです。 あなたはバイナリ・ファイルも コード化することができます。

    print sightly({Shape      => 'camel,mongers',
                   SourceFile => 'some_binary_file',
                   Binary     => 1,
                   Print      => 1,
                   Gap        => 3 } );

これはuuencode/uudecodeよりもキレイです。 以下にsightly.plでバイナリ・ファイルをエンコード/デコードする方法を示します。

エンコード:

    sightly.pl -g3 -bps camel,mongers -f some_binary_file >eyesore

デコード:

    perl eyesore >f.tmp

それが動くかを確認:

    cmp f.tmp some_binary_file

ゆっくりしたい日

本当にゆっくりしたい日には、Unix端末に座り、以下のようにタイプ することができます:

    sightly.pl -r -s camel -f helloworld.pl >t1.pl
    cat t1.pl
    perl t1.pl

この小さなプログラムにはラクダが1頭だけ必要です。

    sightly.pl -r -s camel -f t1.pl >t2.pl
    cat t2.pl
    perl t2.pl

フーム、これでラクダが14頭。

    sightly.pl -r -s camel -f t2.pl >t3.pl
    ls -l t3.pl
    cat t3.pl
    perl t3.pl

ラクダ195頭。563,745バイト。ウーン、遅くなった。 これまでに書かれた最も大きくって、遅いhello worldプログラムじゃない?

    sightly.pl -r -s camel -f t3.pl >t4.pl
    ls -l t4.pl
    cat t4.pl
    perl t4.pl

ラクダ2046頭。5,172,288バイト。メモリがないだって!

Buffyはクリケットに行った

Buffyファンは彼女の文字を回転したいかもしれません:

    print sightly( { Shape       => 'buffy',
                     Rotate      => 0,  # try 270, 90 and 180
                     RotateType  => 1,  # try 0, 1, 2
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

あるいは彼女をポニーに乗せたいかもしれません:

    print sightly( { Shape        => 'buffy3,buffy4,riding,a,pony',
                     SourceString => "This is how Catherine the ".
                                     "Great died.\n",
                     Gap          => 2,
                     Regex        => 1,
                     Print        => 1 } );

一方、クリケットのファンは以下のように比較するかもしれません:

    print sightly( { Shape       => 'cricket',
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

これは以下のものを生成します:

                     '?'
                    =~+(
                   "\(".
                  "\?".
                "\{".(
               ('`')|
              '%').(
             ('[')^
            '-').(    "\`"|
           '!').(   '`'|',')
      .'"'.('['    ^'+').('['
      ^"\)").(     '`'|"\)").(
    '`'|'.')       .('['^'/')
    .(('{')^       '[').'\\'.
  '"'.(('`')|       '(').('`'
 |'%').('`'|','      ).("\`"|
 "\,").( '`'|'/')    .('{'^'[').
 (('[')^  ',').('`'|'/').(('[')^
  "\)").(  '`'|',').('`'|'$').''.
   ('\\').  '\\'.('`'|"\.").'\\'.
     ('"').  ';'.('!'^'+').('"').
      '}'.')');$:='.'^'~';$~='@'|
      '(';$^=')'^'[';$/='`'|'.';$_
       ='('^'}';$,='`'|'!';$\=')'^
        '}';$:=   '.'^'~';$~="\@"|
         '(';      $^=')'^"\[";$/=
                   '`'|'.';$_='('^
                   '}';$,='`'|"\!";
                   $\=')'^('}');$:=
                   '.'^'~';$~="\@"|
                   '(';$^=')'^"\[";
                  $/='`'|'.';$_='('
                 ^'}';$,='`'|'!';$\=
               ')'^'}';$:='.'^'~';$~=
              '@'|'(';$^=')'^('[');$/=
              '`'|'.';$_='('^'}';$,='`'
             |'!';$\=')'^'}';$:='.'^'~';
            $~='@'|'(';$^=')'^'[';$/='`'|
     (     '.');$_='('^'}'   ;$,='`'|"\!";
      $\   =')'^"\}";$:=      '.'^('~');$~=
       '@' |'(';$^=')'^        '[';$/=('`')|
       '.';$_=('(')^            '}';$,=('`')|
       '!';$\=(')')^             '}';$:=('.')^
       '~';$~='@'|'('              ;$^=')'^'[';
        $/='`'|('.');$_=            '('^"\}";$,=
         '`'|'!';$\=')'^'}'           ;$:='.'^'~'
            ;$~='@'|('(');$^=          ')'^"\[";$/=
               '`'|'.';$_='('           ^'}';$,='`'|
                     '!';$\=              ')'^'}';$:=
                      "\."^                 '~';$~='@'|
                     "\(";                    $^=')'^'['
                     ;$/=                      '`'|'.';
                     $_=                         "\(";

そしてこれは:

    print sightly( { Shape       => 'cricket',
                     Invert      => 1,
                     BorderWidth => 2,
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

これを生成します:

 ''=~('('.'?'.'{'.('`'|'%').('['^'-').('`'|'!').('`'|(',')).
 '"'.('['^'+').('['^')').('`'|')').('`'|'.').('['^'/').('{'^
 '[').'\\'.'"'.('`'|'('   ).('`'|'%').('`'|',').('`'|"\,").(
 '`'|'/').('{'^"\[").(    '['^',').('`'|'/').('['^')').('`'|
 ',').('`'|'$').'\\'.     '\\'.('`'|'.').'\\'.'"'.';'.("\!"^
 '+').'"'.'}'."\)");     $:='.'^'~';$~='@'|'(';$^=')'^'[';$/
 ='`'|'.';$_="\("^      '}';$,='`'|'!';$\=')'^'}';$:='.'^'~'
 ;$~='@'|"\(";$^=      ')'^'[';$/='`'|'.';$_='('^'}';$,='`'|
 '!';$\=')'^'}';      $:='.'^'~';$~='@'|'(';$^=')'^('[');$/=
 '`'|'.';$_='('      ^'}';$,='`'|'!';$\=')'^'}';$:='.'^"\~";
 $~='@'|'(';$^      =')'     ^'[';$/='`'|'.';$_='('^"\}";$,=
 '`'|"\!";$\=      ')'        ^'}';$:='.'^'~';$~='@'|'(';$^=
 ')'^'['         ;$/=          '`'|'.';$_='('^'}';$,='`'|'!'
 ;$\=')'        ^'}';           $:='.'^'~';$~='@'|'(';$^=')'
 ^'[';        $/='`'|          '.';$_='('^'}';$,='`'|'!';$\=
 "\)"^        '}';$:=          '.'^'~';$~='@'|'(';$^=')'^'['
 ;$/           =('`')|         '.';$_='('^'}';$,='`'|'!';$\=
 ((              ')'))^        '}';$:='.'^'~';$~='@'|'(';$^=
 ((       (        ')')           ))^'[';$/='`'|'.';$_="\("^
 ((       ((                      '}'))));$,='`'|'!';$\=')'^
 '}'       ;(                      $:)='.'^'~';$~='@'|'(';$^
 =')'       ^+                     '[';$/='`'|'.';$_='('^'}'
 ;($,)=      ((                    '`'))|'!';$\=')'^"\}";$:=
 '.'^'~'                           ;$~='@'|'(';$^=')'^'[';$/
 =('`')|                            '.';$_='('^'}';$,=('`')|
 "\!";$\=                           ')'^'}';$:='.'^('~');$~=
 '@'|"\(";       $^=                ')'^'[';$/='`'|('.');$_=
 '('^'}';$,    ="\`"|               '!';$\=')'^'}';$:=('.')^
 '~';$~='@'|('(');$^=               ')'^'[';$/='`'|('.');$_=
 '('^'}';$,='`'|"\!";                $\=')'^'}';$:='.'^"\~";
 $~='@'|'(';$^=(')')^                '[';$/='`'|'.';$_="\("^
 '}';$,='`'|('!');$\=                ')'^'}';$:='.'^"\~";$~=
 '@'|'(';$^=')'^"\[";                $/='`'|'.';$_='('^"\}";
 $,='`'|'!';$\="\)"^                 '}';$:='.'^'~';$~="\@"|
 '(';$^=')'^'[';$/=                   '`'|'.';$_='('^'}';$,=
 '`'|'!';$\="\)"^                      '}';$:='.'^'~';$~='@'
 |'(';$^=')'^'['                        ;$/='`'|'.';$_="\("^
 '}';$,='`'|'!';                         $\=')'^'}';$:="\."^
 '~';$~='@'|'('                           ;$^=')'^'[';$/='`'
 |'.';$_="\("^                             '}';$,='`'|'!';$\
 ="\)"^ "\}";               $:=             '.'^'~';$~="\@"|
 '(';$^=  ')'             ^"\[";             $/='`'|"\.";$_=
 '('^'}';   (            $,)='`'|             '!';$\=')'^'}'
 ;$:='.'^             '~';$~="\@"|             '(';$^=(')')^
 "\[";$/=             '`'|('.');$_=             '('^"\}";$,=
 '`'|'!';              $\=')'^'}';$:=            '.'^'~';$~=
 '@'|"\(";                $^=')'^"\[";            $/='`'|'.'
 ;$_=('(')^                  '}';$,='`'|           ('!');$\=
 ')'^('}');$:=                 '.'^'~';$~            =('@')|
 '(';$^=')'^"\[";              $/='`'|'.';            $_='('
 ^'}';$,='`'|'!';$\=')'       ^'}';$:=('.')^           "\~";
 $~='@'|'(';$^=')'^"\[";     $/='`'|'.';$_='('           ^((
 '}'));$,='`'|('!');$\=     ')'^'}';$:='.'^"\~";          $~
 ='@'|'(';$^=')'^'[';$/    ='`'|'.';$_='('^'}';$,        =((
 '`'))|'!';$\=')'^"\}";   $:='.'^'~';$~='@'|'(';$^=     ')'^
 '[';$/='`'|'.';$_='('^'}';$,='`'|'!';$\=')'^'}';$:='.'^'~';
 $~='@'|'(';$^=')'^'[';$/='`'|'.';$_='('^'}';$,='`'|"\!";#;#

あるいは、これは:

    print sightly( { Shape       => 'cricket',
                     Invert      => 1,
                     BorderWidth => 1,
                     Reduce      => 1,
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

これを生成します:

 ''=~('('.'?'.'{'.('`'|('%')).(
 '['^"\-").(  '`'|'!').('`'|','
 ).'"'.('['   ^'+').('['^')').(
 '`'|')').   ('`'|'.').('['^'/'
 ).("\{"^   '[').'\\'.'"'.('`'|
 "\(").(   ((  '`'))|'%').('`'|
 ',')    .(     '`'|',').("\`"|
 '/'    ).(     '{'^'[').("\["^
 ((     ',')    )).('`'|"\/").(
 (        ((      '[')))^')').(
 ((   (           '`')))|',').(
 '`'   |          '$').'\\'.''.
 '\\'              .('`'|"\.").
 '\\'.   ((        '"'))."\;".(
 '!'^"\+").        '"'.'}'.')')
 ;$:=('.')^        '~';$~="\@"|
 '(';$^=')'        ^'[';$/='`'|
 ('.');$_=          '('^'}';$,=
 '`'|'!';            $\=')'^'}'
 ;$:='.'              ^"\~";$~=
 '@' |+        (       '(');$^=
 ')'^        '[';       $/='`'|
 '.';       $_='('       ^"\}";
 ($,)=        ('`')|      "\!";
 $\=')'^        "\}";      ($:)
 ='.'^'~';$~    =('@')|     '('
 ;$^=')'^'['   ;$/=('`')|     (
 '.');$_='('  ^'}';$,='`'|   ((
 '!'));$\=')'^'}';$:='.'^'~';#;

リファレンス

見た目のよいエンコーディング(Sightly Encoding)

見た目のよい文字セットには32文字あります:

    ! " # $ % & ' ( ) * + , - . /            (33-47)
    : ; < = > ? @                            (58-64)
    [ \ ] ^ _ `                              (91-96)
    { | } ~                                  (123-126)

見た目のよい文字列は、この集合からひっぱられた文字だけで 構成されます。

ascii_to_sightly関数はASCII文字列(0-255)を見た目のよい文字列に 変換します;sightly_to_asciiはその逆を行います。

関数リファレンス

ascii_to_sightly STRING

ascii文字列STRINGを与えられ、見た目のよい文字列を返します。

sightly_to_ascii STRING

見た目のよい文字列STRINGを与えられ、ascii文字列を返します。

regex_print_sightly STRING

ascii文字列STRINGを与えられ、見た目よくエンコードされ、 正規表現に埋め込まれたprintステートメントを持つPerlプログラム を返します。実行するとプログラムはSTRINGを出力します。

regex_eval_sightly STRING

ascii文字列STRINGでPerlプログラムを与えられ、同等で、 正規表現に埋め込まれたevalステートメントを使う、 見た目よくエンコードされたPerlプログラムを返します。

clean_print_sightly STRING

ascii文字列STRINGを与えられ、見た目よくエンコードされた、 evalを通して実行されるprintステートメントを持ったPerl プログラムを返します。

clean_eval_sightly STRING

ascii文字列STRINGでPerlプログラムが与えられ、evalを通して 実行されるevalステートメントを使う、同等の、見た目よく エンコードされたPerlプログラムを返します。

regex_binmode_print_sightly STRING

ascii文字列STRINGを与えられ、binmode(STDOUT)と正規表現に 埋め込まれたprintステートメントを持つ、見た目よくエンコード されたPerlプログラムを返します。実行するとSTRINGを出力します。 STRINGには0-255の範囲の任意の文字が入ることができることに 注意してください。この関数はバイナリ・ファイルを見た目よく エンコードするために使われます。この関数は、正規表現が バイナリのゼロのように見えないために安全ではありません; 代わりにclean_binmode_print_sightlyを使ってください。

clean_binmode_print_sightly STRING

ascii文字列STRINGを与えられ、binmode(STDOUT)とevalを通して 実行されるprintステートメントを持つ、見た目よくエンコードされた Perlプログラムを返します。実行すると、プログラムはSTRINGを 出力します。 STRINGには0-255の範囲の任意の文字が入ることができることに 注意してください。この関数はバイナリ・ファイルを見た目よく エンコードするために使われます。

get_builtin_shapes

組込まれている形の名前を返します。

get_eye_shapes

eyeシェイプのリストを帰します。eyeシェイプは単に、.eyeという 拡張子を持ち、EyeDrops.pmと同じディレクトリにあるファイルです。

border_shape SHAPESTRING GAP_LEFT GAP_RIGHT GAP_TOP GAP_BOTTOM WIDTH_LEFT WIDTH_RIGHT WIDTH_TOP WIDTH_BOTTOM

形の周りに枠線を引きます。

invert_shape SHAPESTRING

形を反転させます。

reflect_shape SHAPESTRING

形を鏡像にします。

reduce_shape SHAPESTRING FACT

FACTの係数にしたがって形の大きさを縮小します。

expand_shape SHAPESTRING FACT

FACTの係数にしたがって形の大きさを拡大します。

rotate_shape SHAPESTRING DEGREES RTYPE FLIP

時計回りに90、180、270度、形を回転させます。 RTYPE=0 大きな回転されられた形 RTYPE=1 小さな回転させられた形 RTYPE=2 つぶされて回転させられた形 FLIP=1 回転させることに加えて、形をひっくり返します(鏡像にします)。 RTYPE と FLIP は180度には適用されません。

pour_sightly SHAPESTRING PROGSTRING GAP RFILLVAR COMPACT

形を文字列SHAPESTRING、見た目よくエンコードされたプログラムを 文字列PROGSTRING、そして連続する形での空間(GAP)を与えられ、 適切に形が整えられたプログラム文字列を返します。RFILLVARは 埋草変数(filler variable)の配列へのリファレンスです。 埋草変数は2文字:$と句読点文字、で構成される適切な Perl変数です。例えばRFILLVAR = [ '$:', '$^', '$~' ]。 もしCOMPACTが1であれば、コンパクトな見た目のよいエンコーディングを 使います。0であれば、そのままの見た目のよいエンコーディングを 使います。

sightly HASHREF

さまざまな属性について述べたハッシュ・リファレンスHASHREFが 与えられ、適切に整形されたプログラム文字列を返します。

HASHREFに入れることが出来る属性は以下の通りです:

    Shape         あなたが欲しい図形を記述します。
                  最初に、組み込まれている形が探され、次に
                  'eye'シェイプ(EyeDrops.pmと同じディレクトリにある
                  .eyeファイル)が探されます。最後にファイル名が
                  探されます。

    ShapeString   欲しい図形を記述します。
                  この場合は図形の文字列を指定します。

    SourceFile    変換されるソースファイル名

    SourceString  ファイル名の代わりに文字列を指定します。

    BannerString  組込図形'banner'で使われる文字列

    Regex         ブール値。設定されると、ソースプログラムを
                  正規表現に埋め込もうとします。複雑なプログラムを
                  変換するとき、このフラグを設定しないでください。

    Compact       ブール値。設定されるとコンパクトな見た目のよいエンコーディングを使います。

    Print         ブール値。設定されると、デフォルトのevalステートメント
                  の代わりにprintステートメントを使います。
                  (プログラムではなく)テキストファイルを変換するときには
                  このフラグを設定してください。

    Binary        ブール値。エンコーディングがバイナリファイルであれば設定してください。

    Gap           連続する図形の間での行数

    Rotate        図形を時計回りに90、180、270度に回転します。

    RotateType    0 = 大きく回転した図形
                  1 = 小さく回転した図形
                  2 = つぶされ、回転された図形

    RotateFlip    ブール値。図形を回転させ、さらにひっくり返し
                  (反射)させたければ設定してください。

    Reflect       図形を鏡像にします。

    Reduce        図形の大きさを小さくします。

    Expand        図形の大きさを大きくします。

    Invert        図形を反転させます。

    Indent        図形をインデントさせます。インデントするための空白の数。

    BorderGap     図形の周りに枠線をつけます。枠線と図形との
                  隙間。

    BorderGapLeft,BorderGapRight,BorderGapTop,BorderGapBottom
                  上記の1つまたは複数でBorderGapを上書きすることが
                  できます。

    BorderWidth   図形の周りに枠線をつけます。枠線の幅。

    BorderWidthLeft,BorderWidthRight,BorderWidthTop,BorderWidthBottom
                  上記の1つまたは複数でBorderWidthを上書きすることが
                  できます。

    Width         .eyeファイル図形では無視されます。組込図形では、
                  図形に対して適切に、典型的には図形の幅を文字数に
                  適切に解釈されます。図形が指定されないと、Width文字数の
                  長方形のブロックが生成されます。

    TrapEvalDie   ブール値。
                  生成されたプログラムに閉じた'die $@ if $@'を追加します。
                  evalコード・ブロックがdie関数を呼ぶとき、
                  プログラムはdieしません;代わりにdie文字列が$@でevalに
                  返されます。このフラグを使うことにより、dieを呼び出す
                  プログラムdieを変換することが出来ます。

    TrapWarn      ブール値。
                  生成されたプログラムの前に'local $SIG{__WARN__}=sub{};'を
                  加えます。生成されたプログラムが警告を有効にして実行したとき
                  'No such signal: SIGHUP at ...'を吐き出すときに使用してください。

    FillerVar     'filler variables'(埋草変数)もリストへのリファレンス。
                  埋草変数は$と句読点文字の2文字で構成されるPerl変数です。
                  例えば、FillerVar => [ '$:', '$^' ]

図形の指定

以下のように図形を指定すると:

    sightly( { Shape => 'fred' ...

まず組込のfredという図形が探されます、そしてEyeDrops はEyeDrops.pmと 同じディレクトリでfred.eyeファイルを探します。 もしShape属性で'/''.' を指定すると、代わりに、その名前を持つ ファイルが探されます。例えば:

    sightly( { Shape => '/tmp/fred.eye' ...

最後に文字列で図形を指定することもできます。例えば:

    my $shapestr = <<'FLAMING_OSTRICHES';
             #####
    #######################
    FLAMING_OSTRICHES
    sightly ( { ShapeString => $shapestr ...

ソースファイルなしに図形を指定すると:

    print sightly( { Shape => 'camel' } );

no-opの埋め草が図形を埋めます。

図形無しにソースファイルを指定すると:

    print sightly( { SourceFile => 'helloworld.pl' } );

図形がない、空白や改行がまったくない見た目のよい文字列が生成 されます。この文字列はWidth属性によって、固定幅の行に分解する ことができます:

    print sightly( { SourceFile => 'helloworld.pl',
                     Width      => 40 } );

一般的には、組込図形のWidth属性は指定するべきです。Width属性が .eyeファイル図形では無視されることに注意してください。

図形リファレンス

組込図形には以下のものがあります:

    banner      BannerString属性でのテキストの
                Linux banner コマンド (/usr/games/banner -w Width)
    srcbanner   ソーステキストのLinux banner コマンド
                 (/usr/games/banner -w Width)
    siertri     シェルピンスキーの三角形 (2**Width 行)
    triangle    三角形(幅 Width 文字)

このバージョンのEyeDropsで配布される.eyeファイル図形は以下の通りです:

    a           "a"の水平方向のバナー
    acme        オレンジ色が好きなPerl/Parrot Euro-hacker
    alien       エイリアン (Ton Hospelだと噂されている, 1974年ごろの
                Roswell archivesより)
    bleach      "use Acme::Bleach;"の垂直方向のバナー
    buffy       "Buffy"の垂直方向のバナー
    buffy2      Buffyの天使のような顔
    buffy3      ポニーに乗るBuffy
    buffy4      "Buffy"の水平方向のバナー
    camel       ヒトコブラクダ (Camelus dromedarius, one hump)
    camel2      もう一つのヒトコブラクダ (use.perl.orgより)
    camel3      London.pmのロンドン動物園にいるフタコブラクダ
    coffee      一杯のコーヒー
    cricket     このゲームではオーストラリアが世界チャンピオン
    damian      Acmeという名前空間はすべて彼の失敗
    dipsy       テレタビットのディブシー (london.pmのinfobotの名前でもある)
    eugene      Perl golferのチャンピオン, Eugene van der Pijll
    eye         目
    gelly       パリでのY::E 2003の各セッションでの呼び物の講演者
    golfer      1番アイアンを打っているゴルファー
    japh        JAPHはRandal L Schwartzによって1988年に発案されました
    jon         標準的な問題である白いコーヒーカップをホテルの壁にぶつけること
                により、Perl 6の開発を蹴り飛ばしてはじめさせました
    kermit      カエルのカーミット
    larry       Wall, Larry (Wall, RussであるRussell Wallとの対比
                として)
    larry2      Ryan Kingによって寄稿されたLarryのマンガ
    llama       ラマは一緒に繁殖することができるそれほどラクダと密接な
                関係があります。(彼らの子供はcamaと呼ばれます)
    london      俳句 "A Day in The Life of a London Perl Monger"
    merlyn      Just another Perl hacker, 別名 Randal L Schwartz
    mongers     Perl Mongersのロゴ
    mosquito    蚊
    naw         裸の腕相撲 (Y::E 2002, ミュンヘン)
    parrot      初めはエイプリルフールの冗談。冗談が冗談では
                なくなってしまった
    pgolf       Perl Golfのロゴ (`/anickによって招かれた)
    pony        "Pony"の水平方向のバナー
    pony2       ポニーの絵
    riding      "riding"の水平方向のバナー
    santa       ゴルフをしているサンタ・クロース
    schwern     私のとても嫌なこと(=is my bitch)
    simon       parrotの発案者
    spoon       木で出来たスプーン
    tonick      Ton Hospel と `/anicとのゴルフ・コンテストの
                絵による表現;華やかだけどサンスペスにはならない
    tpr         "The Perl Review"の垂直方向のバナー
    uml         UMLダイアグラム
    undies      一組のパンツ
    window      窓
    yanick      `/anickの頭のマンガ
    yanick2     TPR02の間`/anickが口にしていたこと
    yanick3     yanick2の絵によるバージョン
    yanick4     図形yanickの省略したバージョン

あなた独自の図形を作るのは簡単です。図形についてのアイデアは、 Ascii ArtあるいはClip Artに検索エンジンを向けてください。 素晴らしい図形ができたら、EyeDropsの将来のバージョンに入れることが できるように送ってください。

バグ

一種類の文字を数多く持つ、本当に邪悪な図形は図形生成アルゴリズムを 台無しにするかもしれません。

変換されるプログラムが、正規表現と$_の利用に注意している場合に のみ、全ての英数字を(Regex => 1によって)除去することが出来ます。 複雑なプログラムを変換するためには、Regex => 0を使わなければなりません。 それは前に見栄えのよくないevalを吐き出します。

Regex => 1によって生成されたコードは実行するためにPerl 5.005以上を 要求します;前のバージョンで実行すると、エラーメッセージを見ることに なるでしょう: Sequence (?{...) not recognized

変換されたプログラムは、evalの内側で走ります。 これは重大なプログラムで問題を起こすかもしれません。 例えばdieステートメントあるいはINITブロックは、トラブルを起こすかも しれません。もし絶望的であれば、TrapEvalDieTrapWarn 属性を与え、実行し、その問題を修正するかどうかを見てください。

変換されるプログラムがPerlのフォーマット変数$:$~ あるいは $^を使っているならば、プログラムによって使われないPerl変数に 明示的にFillerVar属性を設定する必要があるかもしれません。

Linux /usr/games/bannerは以下の文字をサポートしません:

    \ [ ] { } < > ^ _ | ~

Text::Bannerが拡張されているとき、それはLinux bannerコマンドの場所で 使われます。

作者(AUTHOR)

Andrew Savige <asavige@cpan.org>

参考資料

Acmeの Y::E 2002 裸の腕相撲のムービー http://astray.com/tmp/yapcbits3.mov.

Perl Obfuscation Engines, for example, yaoe by Perl Monk mtve, at http://www.perlmonks.com/index.pl?node_id=161087 and http://www.frox25.dhs.org/~mtve/code/eso/perl/yaoe/.

Perl Monks Obfuscationセクション、特に: http://www.perlmonks.com/index.pl?node_id=45213 (Erudilのcamel code) そして http://www.perlmonks.com/index.pl?node_id=176043 (Lenの Spiralling quine) そして http://www.perlmonks.com/index.pl?node_id=188405 (シェルピンスキーの三角形).

The definitive Perl Golf reference is http://perlgolf.sourceforge.net/.

$|-- のイディオム ( 宙返りするラクダのセクションで 利用される) は、このスレッドで "説明されて"います: http://archive.develooper.com/fwp@perl.org/msg01360.html.

Acme::Bleach Acme::Smirch Acme::Buffy Acme::Pony

クレジット(CREDITS)

I blame Japhy and Ronald J Kimball and others on the fwp mailing list for exposing the ''=~ trick, Jas Nagra for explaining his Acme::Smirch module, and Rajah Ankur and Supremely Unorthodox Eric for provoking me.

I would also like to thank Ian Phillipps, Philip Newton, Ryan King, Michael G Schwern, Robert G Werner, Simon Cozens, and others on the fwp mailing list for their advice on ASCII Art, imaging programs, and on which picture of Larry to use.

Thanks also to Mtv Europe, Ronald J Kimball and Eugene van der Pijll for their help in golfing the program in the Twelve Thousand and Thirty Two Camels section. Keith Calvert Ivey also contributed some levity to this section.

Ideas from Adam Antonik, Mtv Europe, Eugene van der Pijll, Ton Hospel and Keith Calvert Ivey were used in the Sierpinski Triangles section.

The jon shape was derived from: http://www.spidereyeballs.com/os5/set1/small_os5_r06_9705.html. Kudos to Elaine -HFB- Ashton for showing me this.

著作権(=COPYRIGHT)

Copyright (c) 2001-2002 Andrew Savige. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.

翻訳

川合孝典(GCD00051@nifty.ne.jp)