Acme-EyeDrops

 view release on metacpan or  search on metacpan

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

# $eye_dir is the directory containing the .eye file shapes.
# Note: $eye_dir is only eval-hostile line in EyeDrops.pm; do not change it
# for t/19_surrounds.t and "EyeDropping EyeDrops.pm" section of doco relies
# on it. Remove ".pm" from "...Acme/EyeDrops.pm" giving directory name.
my $eye_dir = __FILE__; chop($eye_dir);chop($eye_dir);chop($eye_dir);

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:

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

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

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

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

On 15 August 2003, Perl/Parrot Euro-hacker and modern artist
Leon Brocard (pictured above) marched into a secluded
aranciate-blessed, orange-walled room at MoMA and tossed
a black Victoria's Secret bra (pictured below) into



( run in 1.871 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )