Acme-EyeDrops

 view release on metacpan or  search on metacpan

lib/Acme/EyeDrops.pm  view on Meta::CPAN


sub slurp_yerself { _slurp_tfile($eye_dir . '.pm') }

sub get_eye_dir { $eye_dir }

1;

__END__

=head1 NAME

Acme::EyeDrops - Visual Programming in Perl

=head1 SYNOPSIS

    use Acme::EyeDrops qw(sightly);

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

=head1 DESCRIPTION

C<Acme::EyeDrops> converts a Perl program into an equivalent one,
but without all those unsightly letters and numbers.

In a Visual Programming breakthrough, EyeDrops allows you to pour
the generated program into various shapes, such as UML diagrams,
enabling you to instantly understand how the program works just
by glancing at its new and improved visual representation.

Unlike C<Acme::Bleach> and C<Acme::Buffy>, the generated program runs
without requiring that C<Acme::EyeDrops> be installed on the target
system.

=head1 EXAMPLES

=head2 Getting Started

Suppose you have a program, F<helloworld.pl>, consisting of:

    print "hello world\n";

To convert this little program into an equivalent camel-shaped one,
create F<cvt.pl> as follows:

    # cvt.pl. Convert helloworld.pl into a camel shape.
    use Acme::EyeDrops qw(sightly);
    print sightly( { Shape       => 'camel',
                     SourceFile  => 'helloworld.pl',
                     Regex       => 1 } );

Then run it like this:

    perl cvt.pl >new.pl

After inspecting the newly created program, F<new.pl>, to verify that
it does indeed resemble a camel, run it:

   perl new.pl

to confirm it behaves identically to the original F<helloworld.pl>.

Instead of using the API, as shown above, you may find it more
convenient to use the F<sightly.pl> command in the F<demo> directory:

    sightly.pl -h           (for help)
    sightly.pl -s camel -f helloworld.pl -r 1 >new.pl
    cat new.pl              (should look like a camel)
    perl new.pl             (should print "hello world" as before)

Notice that the shape C<'camel'> is just the file F<camel.eye> in
the F<EyeDrops> sub-directory underneath where F<EyeDrops.pm> is located,
so you are free to add your own new shapes as required.

For the meaning of Regex => 1 above, see the I<Just another Perl hacker>
section below.

=head2 Making Your Programs Easier to Understand

If your boss demands a UML diagram describing your program, you
can give him this:

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

If it is a Windows program, you can indicate that too, by
combining shapes:

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

producing this improved visual representation:

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

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

This is a Visual Programming breakthrough in that you can tell
it is a Windows program and see its UML structure too,
just by glancing at the code.

For Linux only, you can apply its F</usr/games/banner> command
to the program's source text:

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

The generated program is easier to understand than the
original because its characters are bigger and easier to read.

=head2 An Abbreviated History of Perl 6

Here is a summary of the Perl 6 development effort so far:

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

    Design, debate, sift
    Prankster Piers pawky precis
    Weekly light relief

    Gallop Ponie bold!
    Beer to gulp, Buffy astride
    Orange sky surrounds

    Lambda hugs camel
    Precocious pup productive
    Sixth pearl glorious
    END_HAIKU

producing:

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

lib/Acme/EyeDrops.pm  view on Meta::CPAN

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

=head2 Just another Perl hacker

Let's get more ambitious and create a big self-printing I<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 } );

This works. However, if we change:

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

to:

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

the generated program malfunctions in strange ways because
it is running inside a regular expression and Perl's regex engine
is not reentrant. In this case, we must resort to:

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

which runs the generated sightly program via C<eval> instead.
If you want to use Regex => 1 (to eliminate I<all> alphanumerics),
ensure the program to be converted is careful with its use of
regular expressions and C<$_>.

To produce a I<JAPH> that resembles the original
I<Just another Perl hacker,> aka I<Randal L Schwartz>, try this:

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

producing:

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

=head2 Buffy Looking in the Mirror

lib/Acme/EyeDrops.pm  view on Meta::CPAN

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

=head2 99 Bottles of Beer

The web site F<http://www.99-bottles-of-beer.net/> features programs
to display the lyrics of the famous I<99 bottles of beer> song in
over 700 different computer languages.

Over the years, many different Perl solutions have been proposed.
On December 25 1998, for instance, Damian Conway suggested using his
Lingua::EN::Inflect module:

    use Lingua::EN::Inflect 'inflect';
    $n=shift||99;
    print inflect<<BURP while $n;
    NO(bottle of beer,$n) on the wall, NO(bottle of beer,$n)!
    Take one down, pass it around,
    NO(bottle of beer,@{[--$n]}) on the wall.
    BURP

During May 2003, the two leading Perl golfers of that era, Ton Hospel and
Mtv Europe, produced the shortest known Perl solution:

    sub
    b{[@b=(abs||No,bottle."s"x!!++$_,of,beer),on,the,wall]}print
    "@{+b},\n@b,\nTake one down, pass it around,\n@{+b}.\n"
    for-pop||-99..-1

Some years later I noticed that this program can be further shortened
by changing C<"s"> to C<'s'> and embedding the C<sub> inside the first
C<@{}> block like so:

    @{sub b{[@b=(abs||No,bottle.'s'x!!++$_,of,beer),on,the,wall]}b}

This saves a stroke because the first C<+b> in the original is replaced
by a bald C<b>.

Elegant though this solution is, they may have felt a little gobsmacked
when the world's leading I<HQ9+> golfer, Casey West, uncorked a one
stroke solution (C<9>) in that surreal programming language.

To produce a solution shaped like a row of beer bottles, run this:

    use Acme::EyeDrops qw(sightly get_eye_string hjoin_shapes);
    my $ninety_nine = <<'BURP';
    $==pop||99;--$=;sub
    _{($;=($=||No)." bottle"."s"x!!--$=." of beer")." on the wall"}
    print+_,", $;!
    Take one down, pass it around,
    ",_,"!

    "while++$=
    BURP
    chop($ninety_nine); $ninety_nine =~ s/\nprint/print/;
    print sightly( { Regex         => 1,
                     Compact       => 1,
                     ShapeString   => hjoin_shapes(2,
                                      (get_eye_string('bottle2'))x6),
                     SourceString  => $ninety_nine } );

producing:

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

A larger single beer bottle shape can be produced with:

    print sightly( { Regex         => 1,
                     Compact       => 1,
                     Shape         => 'bottle',
                     SourceString  => $ninety_nine } );

while the canonical solution, shaped like 99 bottles of beer, can be
generated with:

    print sightly( { Regex         => 1,
                     ShapeString   => join("\n", (hjoin_shapes(3,
                                      (get_eye_string('bottle2'))x3))x33),
                     SourceString  => $ninety_nine } );

=head2 Sierpinski Triangles

A simple and concise Sierpinski triangle generator, F<siertri.pl>, is:

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

which was posted by Mtv Europe to golf@perl.org on 14-sep-2002
as a one stroke improvement on Adam Antonik's original program.
Running:

    perl siertri.pl 4

displays a Sierpinski triangle with 2**4 lines.

Proclaiming Mtv's program as the shortest (in Acme::EyeDrops 1.13)
only served to provoke Adam Antonik and Eugene van der Pijll into
shortening it by exploiting a hard C<$^F>, as shown in some of the
examples below:

    -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/^ /

An interesting obfuscated Sierpinski triangle generator is:

    #!/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

As an alternative obfu, you can produce a Sierpinski triangle-shaped
Sierpinski triangle generator based on Mtv's program like this:

    print sightly( { Regex           => 1,
                     Compact         => 1,
                     RemoveNewlines  => 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',
                     SourceString    => <<'END_SRC_STR' } );
    $-=!$%<<(pop||4);print$"x$-,map($-&$_?'  ':'/\\',$%..$.++),$/while$---
    END_SRC_STR

producing:

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

lib/Acme/EyeDrops.pm  view on Meta::CPAN



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

=head2 Error Handling

The C<sightly> function returns a properly shaped program string;
there is no error return. If something is badly wrong, C<die> is called.
So if you are calling C<sightly> in an environment where it's
unacceptable to die, be sure to wrap the C<sightly> call in
an C<eval> block. For example:

    eval {
        $prog = sightly( { Shape         => 'invalid-shape',
                           SourceFile    => 'eyesore.pl',
                           InformHandler => sub {} } );
    };
    if ($@) { warn "sightly died: $@\n" }

=head2 EyeDropping EyeDrops.pm

To illustrate EyeDropping a non-trivial module, we convert F<EyeDrops.pm>
itself into a I<bunch o' camels>, via the following generator program,
F<mkeye.pl>:

    use Acme::EyeDrops qw(sightly);
    # Slurp EyeDrops.pm into $orig string.
    my $orig = Acme::EyeDrops::slurp_yerself();
    # Split $orig into the source ($src) and the pod ($doc).
    my ($src, $doc) = split(/\n1;\n/, $orig, 2);
    # Remove the line containing $eye_dir = __FILE__ ...
    # because this line confuses eval.
    $src =~ s/^(my \$eye_dir\b.*)$//m;
    # Generate the new sightly version of EyeDrops.pm.
    print $1, sightly( { Regex         => 0,
                         Compact       => 1,
                         TrapEvalDie   => 1,
                         FillerVar     => ';#',
                         Shape         => 'camel',
                         Gap           => 1,
                         SourceString  => $src } ),
    ";\n1;\n", $doc;

Running this program:

    perl mkeye.pl >m.tmp

produces F<m.tmp>, which can be copied over the top of the original
F<EyeDrops.pm> in the Acme directory. Though the new I<bunch o' camels>
version passes the regression test suite, it's about 4 times slower
than the original.

Notice that we used Regex => 0 (since EyeDrops.pm uses many regular
expressions), TrapEvalDie => 1 (since EyeDrops.pm calls the C<die>
function) and FillerVar => ';#' (to avoid possible warnings due to
unused variables).
Notice too that the only known I<eval-hostile> line in EyeDrops.pm:

    my $eye_dir = __FILE__; ...

was extracted and inserted at the top of the new file.

=head2 Encoding Binary Files

But wait, there's more. You can encode binary files too.

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

This is prettier than I<uuencode/uudecode>.
To encode:

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

To decode:

    perl eyesore >f.tmp

To verify it worked:

    cmp f.tmp some_binary_file

=head2 Victoria Bra, Secret Tango

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

lib/Acme/EyeDrops.pm  view on Meta::CPAN


Changes to Perl 5.18 regex behavior are discussed at
F<http://perlmonks.org/?node_id=1030569>.

The Y::E 2002 I<Dark Art of Obfuscation> talk by Thomas Klausner
at F<http://domm.zsi.at/talks/obfu_yapc2002/>.

Les Perl Mongueurs de Paris $A++ page at
F<http://paris.mongueurs.net/aplusplus.html>.

Yanni Ellen Liu's excellent Ascii Art collection formerly at
F<http://www.cs.umanitoba.ca/~yliu/>.

More information on I<Baghdad Bob> can be found at
F<http://www.welovetheiraqiinformationminister.com/>.

More information on koaladiles (and their relationship to kwalitee)
can be found at
F<http://nntp.perl.org/group/perl.qa/3340>.

The cam.pm Obfuscated Programming Contests at
F<http://cam.pm.org/projects_home.shtml>.

I<Perl Golf> was played monthly at
F<http://perlgolf.sourceforge.net/> and is now played mostly at
F<http://codegolf.com/>. Ton Hospel's excellent generic
golf tester can be got from
F<http://www.xs4all.nl/~thospel/golf/gentest.pl>.

The C<--$|> idiom (exploited in the I<A Somersaulting Camel>
section) is "explained" in this thread:
F<http://archive.develooper.com/fwp@perl.org/msg01360.html>.

L<Acme::Bleach>
L<Acme::Smirch>
L<Acme::Buffy>
L<Acme::Pony>
L<Acme::ChuckNorris>
L<Acme::AsciiArt2HtmlTable>
L<Acme::AsciiArtinator>

=head1 CREDITS

I blame Japhy and Ronald J Kimball and others on the fwp
mailing list for exposing the ''=~ trick, Jas Nagra for
explaining his C<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 I<Twelve Thousand and Thirty Two Camels> section.
Keith Calvert Ivey also contributed some levity to this section.

The "Love Birds" section was provoked by Muss, Jiun and Taffy.
The thumbsup shape was derived from one originally designed by Jiun.

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

Thanks cog for the prod to add new Shape Properties feature.

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

The merlyn shape was derived from this photo
F<http://www.stonehenge.com/merlyn/my_real_proof.jpg>
of Randal singing a duet with Samantha Fox.

The simon shape was derived from a pencil sketch by the Japanese
artist Eiko Yamashita.

The candle, china1, panda and santa2 shapes were derived from similar
ones at Yanni Ellen Liu's Ascii Art collection.

=head1 COPYRIGHT

Copyright (c) 2001-2015 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.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.



( run in 1.264 second using v1.01-cache-2.11-cpan-fe3c2283af0 )