Acme::EyeDrops(3pm)

๐Ÿ“ฆ
version 1.62 ยท 2 versions
  • 1.62 ยท debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking (latest)
  • 1.62 ยท ubuntu jammy
, in debian bookworm, debian trixie, ubuntu noble, ubuntu resolute, ubuntu stonking

๐Ÿฆ‹ Acme::EyeDrops(3pm) ๐Ÿฆ‹

okay bestie, sit down, hydrate, because this is the manual page for Acme::EyeDrops and it is genuinely iconic. it's a Perl module that takes your perfectly normal program and gives it a glow-up so extreme that it stops looking like code and starts looking like art. we're doing Visual Programming today, periodt. ๐Ÿ’…


โœจ NAME โœจ

Acme::EyeDrops - Visual Programming in Perl


๐ŸŒธ SYNOPSIS ๐ŸŒธ

use Acme::EyeDrops qw(sightly);

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

๐Ÿ’– DESCRIPTION ๐Ÿ’–

Acme::EyeDrops takes a Perl program and converts it into an equivalent Perl program, except the new one has had all those unsightly letters and numbers rinsed right out of it. no more ugly alphanumerics cluttering up your vibe. ๐Ÿ˜Œ

In what is, and I say this with my whole chest, a Visual Programming breakthrough, EyeDrops lets you pour the generated program into all kinds of shapes โ€” UML diagrams, animals, whatever โ€” which means you can instantly understand how a program works just by glancing at its new and improved visual representation. reading code with your eyes? over. now you read it with your soul. ๐Ÿ‘‘

And here's the part that really slays: unlike Acme::Bleach and Acme::Buffy, the generated program runs without requiring that Acme::EyeDrops be installed on the target system. no cap. it's self-sufficient. it's independent. it's giving main character energy. ๐Ÿซถ


๐Ÿฆ‹ EXAMPLES ๐Ÿฆ‹

Getting Started

say you've got a program called helloworld.pl, and it's literally just this:

print "hello world\n";

so basic. so cute. but bestie, we can make it a camel.

to convert this little guy into an equivalent camel-shaped program, you make a file called cvt.pl that looks like this:

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

then you run it like this:

perl cvt.pl >new.pl

now go look at your brand new new.pl. inspect it. verify that yes, it does indeed resemble a camel. ๐Ÿช once you've done your vibe check, run it:

perl new.pl

and confirm it behaves identically to the original helloworld.pl. same output, different aesthetic. glow-up complete. โœจ

now โ€” instead of using the API like we just did, you might find it way more convenient to use the sightly.pl command in the 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)

and here's the tea ๐Ÿต: the shape 'camel' is literally just the file camel.eye sitting in the EyeDrops sub-directory underneath wherever EyeDrops.pm lives. so you are free to add your own new shapes as required. go off, make a blorbo.eye. i believe in you.

for the meaning of Regex => 1 up there, go peek at the Just another Perl hacker section below. ๐Ÿ‘€


Making Your Programs Easier to Understand

if your boss demands a UML diagram describing your program, you can hand him this:

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

and if it's 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's a Windows program and see its UML structure too, just by glancing at the code. two facts, zero reading. incredible. ๐Ÿ˜ญโœจ

for Linux only, you can apply its /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. that's it. that's the whole reason. and honestly? valid. ๐Ÿ‘‘


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:

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

there's more coming, bestie โ€” don't go anywhere ๐Ÿ’œ

like okay bestie, this next part is literally the whole flex laid bare โ€” the raw, character-for-character body of it, no edits from me, no glow-up, no filter. just vibes and punctuation ๐Ÿ’…โœจ I'm not touching a single glyph because every one of them is load-bearing, iykyk. here it is, exactly as it lives:

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

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

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

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

so yeah. that's the whole thing, raw, exactly like that ๐Ÿ˜ญ๐Ÿซถ every ^, every |, every stray backslash is doing a job and I am NOT about to mess with any of them. the way this is somehow both a picture and a program at the same time?? it's giving overachiever and I respect it ๐Ÿ’…


ngl this is the part where most people's eyes glaze over and honestly? valid. but stay with me bestie, because the payoff is coming ๐Ÿ”ฅ we're not even close to done here โ€” keep scrolling, there's so much more ๐ŸŒธ

๐Ÿฆ‹ Just another Perl hacker ๐Ÿฆ‹

Okay so bestie, let's get more ambitious and create a big self-printing JAPH. Like, glow-up levels of ambitious. ๐Ÿ’–

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 โ€” and this is the plot twist โ€” 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. It's giving "we can't do this here, bestie." So in this case, we must resort to:

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

which runs the generated sightly program via eval instead. ๐Ÿซถ If you want to use Regex => 1 (to eliminate all alphanumerics), make sure the program to be converted is careful with its use of regular expressions and $_. No cap. ๐Ÿ‘‘

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

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

producing:

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

๐Ÿ’… Buffy Looking in the Mirror ๐Ÿ’…

Because the sightly encoding is not very compact, you sometimes find yourself playing a surreal form of Perl Golf โ›ณ, where the winner is the one with the smallest f.tmp in:

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

Apart from reducing the (key-)stroke count, you must avoid regexes and strive to replace alphanumeric characters with sightly ones, which do not require sightly encoding. ๐ŸŒธ

To illustrate, consider the intriguing problem of creating Buffy looking in the mirror. ๐Ÿชž Let's start with k.pl:

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

Notice that EyeDrops-generated programs, by default, contain no trailing spaces, which complicates the above program. ๐Ÿ˜ญ (It's giving "why is my pretty art ruining my code.")

Buffy looking in the mirror can now be created with:

sightly.pl -r 1 -f k.pl -s buffy2 >b.pl
cat b.pl        (should show Buffy's face)
perl b.pl       (should show Buffy looking in the mirror)

Drat. ๐Ÿ˜ญ This needs two buffy2 shapes. So what do we even do?? Well bestie, you could use the "TrailingSpaces" attribute (that's the -T switch to sightly.pl) to slap the required number of trailing spaces onto each line, which lets you write a way briefer kk.pl:

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

and then finally produce Buffy looking in the mirror with:

sightly.pl -T -r 1 -f kk.pl -s buffy2 >bb.pl

Alternatively โœจ the "Compact" attribute (the -m switch to sightly.pl) could be used to produce a solution that's completely free of any trailing spaces:

sightly.pl -m -r 1 -f k.pl -s buffy2 >buffy.pl
cat buffy.pl     (should show Buffy's face)
perl buffy.pl    (should show Buffy looking in the mirror)

which produces buffy.pl:

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

This is maybe a cleaner solution ๐ŸŽ€ though some people find the plain sightly encoding more pleasing to the eye. ngl, valid. ๐Ÿ’…

Showing the face upside down, rather than reflected, is more easily solved with:

open$%;print+reverse<0>

and easier <em>still</em> for a self-printing shape:

open$%;print<0>                    # self printing
open$%;print+map{y;!-~;#;;$_}<0>   # replace sightly with '#'

๐Ÿชโœจ A Somersaulting Camel โœจ๐Ÿช

Let's extend the Buffy example from the previous section to produce a camel-shaped program capable of somersaulting across the screen when run. ๐Ÿ’–

We start with a generator program, gencamel.pl:

print sightly( { Regex          => 1,
                 Compact        => 1,
                 RemoveNewlines => 1,
                 Indent         => 1,
                 BorderGapRight => 1,
                 Shape          => 'camel',
                 SourceString   => <<'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

Note the use of the Compact and RemoveNewlines attributes, necessary here to squeeze the above program into a single camel shape. ๐Ÿช iykyk

Running this program:

perl gencamel.pl >camel.pl

produces camel.pl:

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

Note: The use of a camel image in association with Perl is a trademark of O'Reilly & Associates, Inc. Used with permission. ๐Ÿ“

You can run camel.pl like this:

perl camel.pl           normal forward somersaulting camel
perl camel.pl b         camel somersaults backwards
perl camel.pl please do a backward somersault
                        same thing

You're totally free to add a leading "#!/usr/bin/perl -w" line to camel.pl, so long as you <em>also</em> add a blank line after this header line. โœจ (yes, the blank line is mandatory bestie, don't skip it ๐Ÿ™ˆ)


๐Ÿช๐Ÿช๐Ÿช Twelve Thousand and Thirty Two Camels ๐Ÿช๐Ÿช๐Ÿช

In a similar way to the somersaulting camel described above, we create a camel-shaped program capable of emitting twelve thousand and thirty two different camels when run. ๐Ÿ‘‘

As usual, we start with a generator program, gencamel.pl:

print sightly( { Regex          => 1,
                 Compact        => 1,
                 RemoveNewlines => 1,
                 BorderGap      => 1,
                 Shape          => 'camel',
                 SourceString   => <<'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

Running this program:

perl gencamel.pl >camel.pl

produces camel.pl, which you can run like this:

perl camel.pl           normal camel
perl camel.pl q         quine (program prints itself)
perl camel.pl m         mirror (camel looking in the mirror)
perl camel.pl i         inverted camel
perl camel.pl u         upside-down camel
perl camel.pl r         rotated camel
perl camel.pl h         horizontally-squashed camel
perl camel.pl v         vertically-squashed camel

And you can further combine the above options, each combination producing a different camel, for example:

perl camel.pl uri

produces a large, bearded camel with a pony-tail, glasses, and a tie-dyed T-shirt. :) ๐Ÿ’œ๐ŸŒˆ

camel.pl also accepts an optional <em>second</em> argument, specifying the character to fill the camel with (default "#"). For example:

perl camel.pl hv        small camel filled with #
perl camel.pl hv "$"    small camel filled with $

Why 12,032 camels? Combining the main options q, m, i, u, r, h, v can produce 128 different camels. And there are 94 printable characters available for the second argument, making a total of 128 * 94 = 12,032 camels. ๐Ÿงฎโœจ


๐Ÿ’ช Naked Arm Wrestling ๐Ÿ’ช

The final auction at Y::E 2002 in Munich featured an epic athletic contest which you can remember with:

okay so here's the next round of examples and bestie they are unhinged in the best way ๐Ÿ’–

use Acme::EyeDrops qw(sightly);
my $s = 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
$s =~ s/ +$//m;
print $s;

๐Ÿ—ฃ๏ธ Baghdad Bob ๐Ÿ—ฃ๏ธ

not me running this and getting pure chaos ๐Ÿ˜ญ Run this program:

print sightly( { Shape             => 'baghdad',
                 Regex             => 1,
                 Compact           => 1,
                 RemoveNewlines    => 1,
                 BorderGap         => 1,
                 BorderWidthLeft   => 3,
                 BorderWidthRight  => 3,
                 BorderWidthTop    => 2,
                 BorderWidthBottom => 8,
                 SourceString      => <<'FAMOUS_COMICAL_ALI_QUOTES' } );
warn+(
"Britain is not worth an old shoe!",
"There are no American infidels in Baghdad!",
"We have them surrounded in their tanks!",
"I speak better English than this villain Bush!")[rand(4)],$/
FAMOUS_COMICAL_ALI_QUOTES

and it produces:

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

๐Ÿบ 99 Bottles of Beer ๐Ÿบ

okay this one is a whole saga ๐Ÿฆ‹ The web site http://www.99-bottles-of-beer.net/ features programs to display the lyrics of the famous 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 "s" to 's' and embedding the "sub" inside the first "@{}" block like so:

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

This saves a stroke because the first "+b" in the original is replaced by a bald "b". โœจ

Elegant though this solution is, they may have felt a little gobsmacked ๐Ÿ˜ญ when the world's leading HQ9+ golfer, Casey West, uncorked a one stroke solution (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 } );

๐Ÿ”บ Sierpinski Triangles ๐Ÿ”บ

A simple and concise Sierpinski triangle generator, 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. ๐Ÿฆ‹โœจ

So like, 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 $^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/^ /

There's this interesting obfuscated Sierpinski triangle generator that's giving major main character energy:

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

and it's producing:

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

Dueling Dingos ๐Ÿ’ƒ๐Ÿ•

Okay so during the TPR02 Perl Golf tournament, /anick composed a poem describing his experience, entitled Dueling Dingos.

You can produce a program that emits his moving poem like this, bestie:

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

The generated program is 2577 lines long, so it is not reproduced here. To generate a shorter program summarising `/anick's TPR02 anguish:

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

and it's producing:

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

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

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

โœจ Error Handling โœจ

Okay bestie, real talk about errors: the sightly function returns a properly shaped program string, and that is it โ€” there is no error return. Like, none at all. If something is badly wrong, sightly calls die. So if you're calling sightly in an environment where it is not acceptable to die, please please please be sure to wrap the sightly call in an eval block. For example:

eval {
    $prog = sightly( { Shape         => 'invalid-shape',
                       SourceFile    => 'eyesore.pl',
                       InformHandler => sub {} } );
};
if ($@) { warn "sightly died: $@\n" }
โš ๏ธ no error return, only die. Wrap it in eval if dying is not the vibe. ๐Ÿซถ

๐Ÿช EyeDropping EyeDrops.pm ๐Ÿช

To illustrate EyeDropping a non-trivial module, we convert EyeDrops.pm itself into a bunch o' camels, via the following generator program, 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 m.tmp, which can be copied over the top of the original EyeDrops.pm in the Acme directory. And ngl, even though the new 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 die function) and FillerVar => ';#' (to avoid possible warnings due to unused variables). Notice too that the only known eval-hostile line in EyeDrops.pm:

my $eye_dir = __FILE__; ...

was extracted and inserted at the top of the new file. ๐ŸŽ€


๐Ÿ’พ 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 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

๐Ÿ‘‘ 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 the air, thereby creating a brilliant contemporary site-specific art exhibit. ๐ŸŒˆ๐Ÿ’–

and here she is, bestie. the shape. the whole shape. pure Perl, no cap ๐Ÿ’–

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

The bra, donated by Elaine -HFB- Ashton, was bought by the artist expressly for this artwork at the YAPC::Europe 2003 auction.

the artist bought a literal bra at a Perl conference auction to make it into Perl art. we have no choice but to stan. ๐Ÿ‘‘

An interpretation of Brocard's modern masterpiece is given below:

Victoria Bra, Secret Tango (2003) L. Brocard 1976- This one is the third work in Brocard's acclaimed "Naranja" sequence, and it absolutely goes off on the theme of semantic [a]chromatic aspects of aranciata visual perception, which he first explored in his celebrated "Buffy" series โ€” and it fully explores the concept of supporting relationships, which he'd only touched on in his earlier works. The site's central artifact is a stark reminder of the lack of support in contemporary relationships, and the jumbled juxtaposition of its two cups โ€” literally giving "discarded in a hurry" โ€” symbolizes the excessive rapidity and tautness of modern life. And as always with Brocard, it is vital to consider the intertextuality of the title of the work, so you can deconstruct the surface meaning of the work itself and penetrate, as it were, to the kernel of the work's "meaning" โ€” if such a concept is still relevant in the present context. Consider, for example, the word "Victoria": does it express the moniker of the bra's former occupant, or merely the state or district in which she was born? And what of "Secret Tango"? In the context of the universe that is the present work, is it merely indicative of the site's location and visual perception, or does it suggest the bra's former resident once furtively enjoyed a rhythmic dance of long gliding steps and sudden pauses with the artist? The viewer will no doubt at this point recall that the word "tango" rhymes with "mango" and thereby grasp the semantic thrust of the work's title. However, the installation itself has even more to reveal when the particularly observant viewer speculates on the site's central device being strapped to its current owner's chiseled torso.
โš ๏ธ This work is extremely fragile. Please do not touch. โš ๏ธ

okay but the way "tango" rhymes with "mango" is genuinely the whole thesis here and the art world just wasn't ready. iykyk ๐Ÿฅญ๐Ÿ’ƒ


๐Ÿ’– Love Birds ๐Ÿ’–

My Dark Tunnels teammate Taffy is devoted to โ€” and firmly believes in โ€” a love calculator web site where you type in two names and it reports your love compatibility.

so obviously we calculated the love compatibility of our entire team, and it came out disappointingly low, with one notable exception. Taffy and Muss recorded an astonishingly high love compatibility of ninety nine percent โ€” the highest ever recorded! ๐Ÿ˜ญ๐Ÿ’˜

As a tribute to their affectionate and touching bromance, I wrote this program:

use Acme::EyeDrops qw(sightly get_eye_string hjoin_shapes);
print sightly( { ShapeString   => hjoin_shapes(3, (get_eye_string('heart2'))x2),
                 SourceString => "Muss and Taffy have 99% Love Compatibility\n",
                 Regex        => 1,
                 Print        => 1 } );

to generate:

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

By the way, this is the same heart shape that Perl Monk Falkkin used to successfully propose to his girlfriend Kristen in August 2004.

not the Perl Monk proposal lore ๐Ÿ˜ญ๐Ÿ’ obsessed with them fr fr


๐Ÿฆ‹ Buffy Goes to the Cricket ๐Ÿฆ‹

Buffy fans might like to rotate her letters:

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

or have her ride a pony:

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

while cricket fans might create a reduced, inverted shape with:

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

producing:

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

Buffy rotating, Buffy on a pony, and a reduced inverted cricket โ€” she contains multitudes, honestly. ๐Ÿ’…


โ„๏ธ Snowflakes โ„๏ธ

The "Text" and "TextFiller" attributes (-t/-u switches to sightly.pl) are handy when you simply want to pour some unsightly text into a shape. iykyk ๐Ÿซถ

To illustrate, consider an entry in the Cam.pm 2002 Christmas programming contest, snowing.pl:

$_=q~vZvZ&%('$&"'"&(&"&$&"'"&$Z$#$$$#$%$&"'"&(&#
%$&"'"&#Z#$$$#%#%$%$%$%(%%%#%$%$%#Z"%*#$%$%$%$%(%%%#%$%$
%#Z"%,($%$%$%(%%%#%$%$%#Z"%*%"%$%$%$%(%%%#%$%$%#Z#%%"#%#%
$%$%$%$##&#%$%$%$%#Z$&""$%"&$%$%$%#%"%"&%%$%$%#Z%&%&#
%"'"'"'###%*'"'"'"ZT%?ZT%?ZS'>Zv~;
s;\s;;g;
$;='@,=map{$.=$";join"",map((($.^=O)x(-33+ord)),/./g),$/}split+Z;
s/./(rand)<.2?"o":$"/egfor@;=((5x84).$/)x30;map{
system$^O=~W?CLS:"clear";print@;;splice@;,-$_,2,pop@,;
@;=($/,@;);sleep!$%}2..17';
$;=~s;\s;;g;eval$;

The rules of this contest state that the program source code must fit precisely into the provided snowflake shape. To comply, you can pour the above program into the required shape with:

sightly.pl -s snow -f snowing.pl -t -u# -n1 >snowflake.pl

or equivalently (using the API instead of sightly.pl):

print sightly( { Shape       => 'snow',
                 SourceFile  => 'snowing.pl',
                 Text        => 1,
                 TextFiller  => '#',
                 Indent      => 1 } );

producing a valid entry, snowflake.pl:

            $_=                          q~v
          ZvZ&%('                      $&"'"&(
         &"&   $&"'  "&$Z$#$$$#$%$&  "'"&   (&#
          %$&"'"&#Z#$$    $#%#    %$%$%$%(%%%#
          %$%$%#Z"%*#$    %$%$    %$%(%%%#%$%$
         %#  Z"%,   ($%    $%    $%(   %%%#  %$
        %$%    #Z"   %*%"  %$  %$%$   %(%    %%#
       %$%$%#   Z#%%"#%#%$ %$ %$%$##&#%$   %$%$%#
      Z$     &""$%"&$%$%$%#%"%"&%%$%$%#Z%&%     &#
  %"'"'"'###%*'"'"'"ZT%?ZT%?ZS'>Zv~;s;\s;;g;$;='@,=map
 {$.=  $";join""  ,map((($    .^=O)x(-  33+ord)),  /./g
 ),$    /}split    +Z;s/.      /(rand    )<.2?"o    ":$
 "/eg  for@;=((5  x84).$/)    x30;map{  system$^O  =~W?
  CLS:"clear";print@;;splice@;,-$_,2,pop@,;@;=($/,@;);
      sl     eep!$%}2..17';$;=~s;\s;;g;eval     $;
       ######   ########## ## ##########   ######
        ###    ###   ####  ##  ####   ###    ###
         ##  ####   ###    ##    ###   ####  ##
          ############    ####    ############
          ############    ####    ############
         ###   ####  ##############  ####   ###
          #######                      #######
            ###                          ###

Running snowflake.pl produces a pretty "cam.pm" snow-scape. The leftover space at the bottom could be used to add a snowman:

                   $_=                          q~v
                 ZvZ&%('                      $&"'"&(
                &"&   $&"'  "&$Z$#$$$#$%$&  "'"&   (&#
                 %$&"'"&#Z#$$    $#%#    %$%$%$%(%%%#
                 %$%$%#Z"%*#$    %$%$    %$%(%%%#%$%$
                %#  Z"%,   ($%    $%    $%(   %%%#  %$
               %$%    #Z"   %*%"  %$  %$%$   %(%    %%#
              %$%$%#   Z#%%"#%#%$ %$ %$%$##&#%$   %$%$%#
             Z$     &""$%"&$%$%$%#%"%"&%%$%$%#Z%&%     &#
         %"'"'"'###%*'"'"'"ZT%?ZT%?ZS'>Zv~;s;\s;;g;$~=q~ZZZJ_
        #_ZH  /'\\ZG|#o  #o#|ZG|$    <%|ZH\\"  \\!_!_!/"  /ZG/
        )\\    ZF/+\\Z    E|-|ZE      |-|ZE|    -|ZF\\+    /ZG
        \\)/  ~;;@x=@,=  +map{$.=    $";;join  "",map(((  $.^=
         O)x(-33+ord)),/./g)}split+Z;$~=~s~\s~~g;;s;.;(rand)<
             .2     ?"o":$";egxfor@;=(5x84)x30;map     {#
              system   $^O=~W?CLS :+ "clear";;;   ;print
               $_.    $/,   ,for  $_  -18?   @;:    ###
                ((  map{   $|=    1;    ;;;   join  ""
                 ,map($|--?$"    x(-3    *11+ord):$_,
                 /./g)}split+    Z,$~    ),@x);splice
                @;,   -$_,  2,pop@,;@;=(""  ,@;)   ;;;
                 ;sleep!                      $%}+2..
                   18#                          /-\

โœจ REFERENCE โœจ

๐Ÿ’– Sightly Encoding ๐Ÿ’–

There are 32 characters in the sightly character set:

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

A sightly string consists only of characters drawn from this set.

The ascii_to_sightly function converts an ASCII string (0-255) to a sightly string; the sightly_to_ascii function does the reverse.


๐ŸŒˆ Function Reference ๐ŸŒˆ

okay bestie, this is the whole function menu, no skips, no cap ๐Ÿซถ

๐Ÿ’… ascii_to_sightly STRING

Given an ascii string STRING, returns a sightly string.

๐Ÿฆ‹ sightly_to_ascii STRING

Given a sightly string STRING, returns an ascii string.

โœจ regex_print_sightly STRING

Given an ascii string STRING, returns a sightly-encoded Perl program with a print statement embedded in a regular expression. When run, the program will print STRING.

๐ŸŽ€ regex_eval_sightly STRING

Given a Perl program in ascii string STRING, returns an equivalent sightly-encoded Perl program using an eval statement embedded in a regular expression.

๐Ÿ’– clean_print_sightly STRING

Given an ascii string STRING, returns a sightly-encoded Perl program with a print statement executed via eval. When run, the program will print STRING.

๐ŸŒธ clean_eval_sightly STRING

Given a Perl program in ascii string STRING, returns an equivalent sightly-encoded Perl program using an eval statement executed via eval.

๐Ÿ”ฅ regex_binmode_print_sightly STRING

Given an ascii string STRING, returns a sightly-encoded Perl program with a binmode(STDOUT) and a print statement embedded in a regular expression. When run, the program will print STRING. Note that STRING may contain any character in the range 0-255. This function is used to sightly-encode binary files.

This function is dodgy because regexs don't seem to like binary zeros; use clean_binmode_print_sightly instead. ๐Ÿ’€

๐Ÿ‘‘ clean_binmode_print_sightly STRING

Given an ascii string STRING, returns a sightly-encoded Perl program with a binmode(STDOUT) and a print statement executed via eval. When run, the program will print STRING. Note that STRING may contain any character in the range 0-255. This function is used to sightly-encode binary files.

๐Ÿงš get_builtin_shapes

Returns a list of the built-in shape names.

๐Ÿ’œ get_eye_dir

Returns the directory containing the .eye file shapes. This is the EyeDrops sub-directory underneath where EyeDrops.pm is located.

๐Ÿ“ get_eye_shapes

Returns a list of the eye shapes in ascii-betical order. An eye shape is just a file with a .eye extension residing in the get_eye_dir directory.

โญ get_eye_keywords

Returns a hash reference keyed by keyword, with the value being the list of shapes containing the keyword.

๐ŸŒˆ find_eye_shapes KEYWORDLIST

Returns a list of the eye shapes in ascii-betical order that contain all keywords in KEYWORDLIST. The keywords in KEYWORDLIST are implicitly AND'ed together. Additionally, you may use OR inside any KEYWORDLIST element. If this is unclear, see the examples in "Shape Properties" section below.

๐ŸŽ€ get_eye_string SHAPENAME

Given a .eye SHAPENAME, returns the shape string.

๐Ÿ’… get_eye_properties SHAPENAME

Given a .eye SHAPENAME, returns a hash reference of the shape properties or undef if the shape has no properties.

๐Ÿซถ slurp_yerself

Returns a string containing the contents of EyeDrops.pm.

โœจ make_triangle WIDTH

Returns a triangle shaped string of WIDTH characters.

๐Ÿ”ฅ make_siertri WIDTH

Returns a Sierpinski triangle shaped string containing 2**WIDTH lines.

๐Ÿ‘‘ make_banner WIDTH STRING

Linux only. Returns a banner of STRING, using the Linux command /usr/games/banner -w WIDTH.

๐ŸŒธ border_shape SHAPESTRING GAP_LEFT GAP_RIGHT GAP_TOP GAP_BOTTOM WIDTH_LEFT WIDTH_RIGHT WIDTH_TOP WIDTH_BOTTOM

Put a border around a shape.

๐Ÿฆ‹ invert_shape SHAPESTRING

Invert a shape.

๐Ÿ’– reflect_shape SHAPESTRING

Reflect a shape.

๐Ÿ“ reduce_shape SHAPESTRING FACT

Reduce the size of a shape by a factor of FACT.

๐Ÿ’œ expand_shape SHAPESTRING FACT

Expand the size of a shape by a factor of FACT.

โญ rotate_shape SHAPESTRING DEGREES RTYPE FLIP

Rotate a shape clockwise thru 90, 180 or 270 degrees. RTYPE=0 big rotated shape, RTYPE=1 small rotated shape, RTYPE=2 squashed rotated shape. FLIP=1 to flip (reflect) shape in addition to rotating it. RTYPE and FLIP do not apply to 180 degrees.

๐ŸŒˆ hjoin_shapes GAP SHAPESTRINGLIST

Join the shapes specified by SHAPESTRINGLIST horizontally with GAP spaces between each shape.

๐ŸŽ€ pour_text SHAPESTRING TEXTSTRING GAP FILLTEXT

Given a shape string SHAPESTRING, a string TEXTSTRING, and a GAP between successive shapes, returns a properly shaped string. That is, pour TEXTSTRING into SHAPESTRING. FILLTEXT (typically '#') is text to be used as a filler for any leftover part of the shape (if not set, don't fill in leftovers).

๐Ÿ’… pour_sightly SHAPESTRING PROGSTRING GAP RFILLVAR COMPACT IH

Given a shape string SHAPESTRING, a sightly-encoded program string PROGSTRING, and a GAP between successive shapes, returns a properly shaped program string. That is, pour PROGSTRING into SHAPESTRING. RFILLVAR is either a reference to an array of filler variables or, alternatively, a string to fill the leftover of the last shape with. Common filler strings are '' for no filler at all, or '#' or ';' or ';#'. A filler variable is a valid Perl variable consisting of two characters: $ and a punctuation character. For example, RFILLVAR = "[ '$:', '$^', '$~' ]". Do not use $; or $" or $_ as filler variables. If COMPACT is 1, use compact sightly encoding, if 0 use plain sightly encoding. If IH (inform handler) is undef, prints status of what it is doing to STDERR; you can override this by providing a subroutine reference taking a single inform string argument. To shut it up, set IH to sub {}.

๐Ÿ‘‘ sightly HASHREF

Given a hash reference, HASHREF, describing various attributes, returns a properly shaped program string. There is no error return; if something is badly wrong, die is called -- so wrap the call to sightly in an eval block if you can't afford to die.

The attributes that HASHREF may contain are:

  • Shape โ€” Describes the shape you want. First, a built-in shape is looked for. Next, a 'eye' shape (.eye file in the get_eye_dir() directory unless overridden by the EyeDir attribute) is looked for. Finally, a file name is looked for.
  • ShapeString โ€” Describes the shape you want. This time you specify a shape string.
  • SourceFile โ€” The source file name to convert.
  • SourceHandle โ€” Specify a file handle instead of a file name.
  • SourceString โ€” Specify a string instead of a file name.
  • BannerString โ€” String to use with built-in Shape 'banner'.
  • Regex โ€” Regex can take the following values:
    • 0: do not embed source program in a regex
    • If Regex is positive, embed the program in a regex and:
      • 1: add a leading "use re 'eval';" for Perl 5.18+ only
      • 2: do not add a leading "use re 'eval';"
      • 3: add a leading "use re 'eval';"
    • Do not set this flag when converting complex programs.
  • Compact โ€” Boolean. If set, use compact sightly encoding.
  • Print โ€” Boolean. If set, use a print statement instead of the default eval statement. Set this flag when converting text files (not programs).
  • Binary โ€” Boolean. Set if encoding a binary file.
  • Text โ€” Boolean. Set if pouring unsightly text.
  • TextFiller โ€” Filler string used with Text attribute. For example, TextFiller => '#'.
  • Gap โ€” The number of lines between successive shapes.
  • Rotate โ€” Rotate the shape clockwise 90, 180 or 270 degrees.
  • RotateType โ€” 0 = big rotated shape, 1 = small rotated shape, 2 = squashed rotated shape.
  • RotateFlip โ€” Boolean. Set if want to flip (reflect) the shape in addition to rotating it.
  • Reflect โ€” Boolean. Reflect the shape.
  • Reduce โ€” Reduce the size of the shape.
  • Expand โ€” Expand the size of the shape.
  • Invert โ€” Boolean. Invert the shape.
  • Indent โ€” Indent the shape. The number of spaces to indent.
  • TrailingSpaces โ€” Boolean. Ensure all lines of the shape are of equal length, adding trailing spaces if required.
  • RemoveNewlines โ€” Boolean. Remove all newlines from the source before conversion.
  • BorderGap โ€” Put a border around the shape. Gap between border and the shape.
  • BorderGapLeft,BorderGapRight,BorderGapTop,BorderGapBottom โ€” You can override BorderGap with one or more from the above.
  • BorderWidth โ€” Put a border around the shape. Width of border.
  • BorderWidthLeft, BorderWidthRight, BorderWidthTop, BorderWidthBottom โ€” bestie, you can override BorderWidth with one or more of these four. Mix and match, go off ๐Ÿ’…
  • Width โ€” lowkey ignored for .eye file shapes, ok? For the built-in shapes it gets interpreted appropriately for whatever shape you picked, typically as the shape width in characters. And if you didn't specify any shape at all? You get a rectangular block of Width characters. Boom. ๐Ÿ“
  • EyeDir โ€” normally .eye files get pulled from the EyeDrops directory underneath wherever EyeDrops.pm is living. You can override that by handing it a directory that contains your .eye shape files. Custom shapes era ๐Ÿ’–
  • InformHandler โ€” by default, sightly prints status of what it's doing to STDERR. You can override this by giving it a subroutine reference that takes a single inform string argument. Want it to just shut up? Set it to sub {}. Iconic. ๐Ÿคซ
  • TrapEvalDie โ€” Boolean. Adds a closing die $@ if $@ to the generated program. Here's the tea: when an eval code block calls the die function, the program doesn't die โ€” instead the die string is returned to eval in $@. Using this flag lets you convert programs that call die. ๐Ÿชค
  • TrapWarn โ€” Boolean. Adds a leading local $SIG{__WARN__}=sub{}; to the generated program. This shuts up some warnings. Use this option if your generated program emits 'No such signal: SIGHUP at ...' when run with warnings enabled. No more noise ๐ŸŽง
  • FillerVar โ€” a reference to a list of 'filler variables'. A filler variable is a Perl variable made of exactly two characters: $ and a punctuation character. Like, for example, FillerVar => [ '$:', '$^' ]. Do not use $; or $" or $_ as filler variables. Alternatively, you may set this to '' if you don't want any filler at all, or to a string (e.g. '#' or ';' or ';#') to use instead of filler variables to fill the leftover part of the last shape with. ๐Ÿงฉ

โœจ Specifying a Shape โœจ

Okay so when you specify a shape like this:

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

first a built-in "fred" shape is looked for, and then EyeDrops goes looking for the file fred.eye in the get_eye_dir directory. But if you put a / or a . in the Shape attribute, it looks for a file with that name instead, like:

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

And finally โ€” plot twist โ€” you can specify a shape with a string, like:

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

If you specify a shape without a source file:

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

a no-op filler is used to fill the shape. ๐Ÿคทโ™€๏ธ

If you specify a source file without a shape:

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

you get a shapeless sightly string with no spaces or newlines. Want to break that string into fixed width lines? Use the Width attribute:

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

Generally you should specify the Width attribute of built-in shapes. And heads up โ€” the Width attribute is ignored for .eye file shapes. ๐Ÿšซ


๐Ÿฆ‹ Shape Reference ๐Ÿฆ‹

The built-in shapes are:

  • banner โ€” Linux banner command (/usr/games/banner -w Width) of text in BannerString attribute
  • srcbanner โ€” Linux banner command (/usr/games/banner -w Width) of source text
  • siertri โ€” A Sierpinski triangle (2**Width lines)
  • triangle โ€” A triangle (width Width characters)
  • all โ€” A shape consisting of all .eye shapes joined together (Width blank lines between each shape)

The .eye file shapes distributed with this version of EyeDrops are:

  • a โ€” Horizontal banner of "a"
  • acme โ€” Perl/Parrot/Ponie Euro-hacker and modern artist who likes the colour orange and enjoys having his bra-strap twanged
  • adrianh โ€” Perl qa expert
  • alien โ€” An alien (rumoured to be Ton Hospel, from the Roswell archives circa 1974)
  • alpaca โ€” Lama pacos, from South America, with long shaggy hair and related to the llama
  • autrijus โ€” The father of Pugs
  • baghdad โ€” Baghdad Bob aka Comical Ali
  • beer โ€” Beer glass designed by Matthew Byng-Maddick for the cam.pm Beerfestival Perl Programming Contest 2002
  • bighorn โ€” Ovis canadensis (bighorn sheep) found in the Rocky Mountains
  • bleach โ€” Vertical banner of "use Acme::Bleach;"
  • bottle โ€” A bottle of beer
  • bottle2 โ€” Abbreviated version of shape bottle
  • bottle3 โ€” A bottle of champagne with a champagne glass
  • bra โ€” A bra
  • buffy โ€” Vertical banner of "Buffy"
  • buffy2 โ€” Buffy's angelic face
  • buffy3 โ€” Buffy riding a pony
  • buffy4 โ€” Horizontal banner of "Buffy"
  • camel โ€” Dromedary (Camelus dromedarius, one hump)
  • camel2 โ€” Another dromedary (from use.perl.org)
  • camel3 โ€” London.pm's bactrian camel at London zoo
  • campm โ€” Horizontal banner of "cam.pm"
  • candle โ€” A Christmas candle
  • china1 โ€” Chinese characters, roughly translated as "God is added a year of seniority; human is added a year of age, Spring fills the universe; luck and happiness fills the family"
  • coffee โ€” A cup of coffee
  • cricket โ€” Australia are world champions in this game
  • damian โ€” The Acme namespace is all his fault
  • dan โ€” The father of parrot
  • debian โ€” Debian logo (contributed by Richard Hartmann)
  • dipsy โ€” Teletubbies Dipsy (also london.pm infobot name)
  • eugene โ€” Champion Perl golfer, Drs Eugene van der Pijll of Utrecht, Holland
  • eye โ€” An eye
  • flag_canada โ€” Canada's flag, contributed by `/anick
  • gelly โ€” Featured speaker at every session of Y::E 2003, Paris
  • golfer โ€” A golfer hitting a one iron
  • halloween โ€” A witch riding a broomstick
  • heart โ€” A heart shape contributed by `/anick
  • heart2 โ€” A heart shape modelled on one by Falkkin
  • hipowls โ€” A pair of hip owls
  • japh โ€” JAPHs were invented by Randal L Schwartz in 1988
  • jon โ€” Kick-started the Perl 6 development effort by smashing a standard-issue white coffee mug against a hotel wall
  • jon_oxer โ€” Linux Australia bigwig (contributed by Paul Fenwick)
  • kangaroo โ€” A kangaroo
  • kansai_pm โ€” Kansai.pm's mascot (Tiger with Perl characters) contributed by Takanori KAWAI (Japanese)
  • kermit โ€” Kermit the frog
  • koaladile โ€” A cross between a koala and a crocodile
  • larry โ€” Wall, Larry (as opposed to Russell Wall who is Wall, Russ)
  • larry2 โ€” Caricature of Larry contributed by Ryan King
  • llama โ€” Llamas are so closely related to camels they can breed with them (their progeny are called camas)
  • london โ€” Haiku "A Day in The Life of a London Perl Monger"
  • map_australia โ€” Map of Australia
  • map_italy โ€” Map of Italy
  • map_japan โ€” Map of Japan
  • map_uk โ€” Map of United Kingdom and Ireland
  • map_world1 โ€” World globe, Asian view
  • map_world2 โ€” World globe, African view
  • map_world3 โ€” World globe, American view
  • merlyn โ€” Just another Perl hacker, aka Randal L Schwartz
  • mongers โ€” Perl Mongers logo
  • moose โ€” A moose
  • moosecamel โ€” A moose and a camel (modelled after http://irclog.perlgeek.de)
  • mosquito โ€” A mosquito
  • music โ€” A musical symbol
  • naw โ€” Naked Arm Wrestling (Y::E 2002, Munich)
  • opera โ€” Opera browser logo (contributed by Cosimo)
  • panda โ€” A panda designed by Yanni Ellen Liu
  • parrot โ€” Originally an April fool's joke, the joke was that it was not a joke
  • pgolf โ€” Perl Golf logo (inspired by `/anick)
  • pony โ€” Horizontal banner of "Pony"
  • pony2 โ€” Picture of a Pony
  • pugs โ€” Horizontal banner of "Pugs"
  • pugs2 โ€” Picture of a Pugs dog
  • riding โ€” Horizontal banner of "riding"
  • rose โ€” A rose
  • santa โ€” Santa Claus playing golf
  • santa2 โ€” Santa Claus carrying presents
  • saturn โ€” The planet Saturn
  • schwern โ€” is my bitch
  • schwern2 โ€” Shape schwern without the banner
  • simon โ€” The inventor of parrot
  • smiley โ€” A smiley face
  • smiley2 โ€” Pulling a face
  • smiley3 โ€” A sad face
  • smiley4 โ€” Another sad face
  • snow โ€” Snowflake designed by Matthew Byng-Maddick for the cam.pm Christmas Perl Programming Contest 2002
  • spider โ€” A spider (tarantula)
  • spoon โ€” A wooden spoon
  • thumbsup โ€” A thumbs up shape modelled on one by Jiun
  • tonick โ€” Pictorial representation of a golf contest between Ton Hospel and `/anick; colourful but not very suspenseful
  • tpr โ€” Vertical banner of "The Perl Review"
  • uml โ€” A UML diagram
  • undies โ€” A pair of underpants
  • window โ€” A window
  • writing_perl โ€” Perl in camel-style by Takanori KAWAI (Japanese)
  • yanick โ€” Caricature of `/anick's noggin
  • yanick2 โ€” Uttered by `/anick during TPR02
  • yanick3 โ€” Pictorial version of yanick2
  • yanick4 โ€” Abbreviated version of shape yanick

It is easy to create your own shapes, bestie, for real. For some ideas on shapes, point your search engine at Ascii Art or Clip Art. And if you generate some nice shapes, please send them in so they can be included in future versions of EyeDrops. Your art could be canon ๐Ÿ’–๐Ÿซถ


๐ŸŒธ Shape Properties ๐ŸŒธ

All the .eye shape files have a corresponding .eyp shape property file, specifying the shape's properties. Cute, right? A whole little sidecar situation ๐Ÿ’…

Currently, the allowed shape properties are:

  • name
  • nick
  • description
  • cpanid
  • author
  • authorcpanid
  • source
  • keywords

where valid keywords are:

  • face
  • person
  • perlhacker
  • animal
  • object
  • planet
  • map
  • flag
  • sport
  • underwear
  • hbanner
  • vbanner
  • logo
  • debian
  • opera

Wanna see how shape properties actually get used in the wild? Say you want every single shape that's just the lil face of a perl hacker. Bestie, it's literally this:

use Acme::EyeDrops qw(find_eye_shapes);
my @perlhackers = find_eye_shapes('face',
                                  'person',
                                  'perlhacker');

Heads up though: there's a secret implicit AND between every keyword, no cap. So that code up there? It's finding all shapes that are face AND person AND perlhacker. All three, every time.

And you can drop an OR into any argument too, like:

my @perlhackers = find_eye_shapes('face',
                                  'person OR animal',
                                  'perlhacker');

which finds everything matching face AND (person OR animal) AND perlhacker. The vibes are math and the math is vibing. โœจ

Don't wanna mess with the API at all? Totally valid. There's a findshapes.pl command chillin' in the demo directory:

findshapes.pl -h           (for help)
findshapes.pl -v face person perlhacker

That last one shows you the faces and the properties of literally every perl hacker shape. Gorgeous.

โš ๏ธ Okay important lil disclaimer bestie: these shape properties are experimental and might change in future A::E releases. Don't build your whole personality on them. ๐Ÿ™ˆ

๐Ÿ› BUGS ๐Ÿ› (the messy parts, we love her anyway)

A truly diabolical shape โ€” like one with a ton of single character lines โ€” will absolutely defeat the shape-pouring algorithm. It's giving chaos and the algorithm is not surviving it. ๐Ÿ’€

You can eliminate all alphanumerics (via Regex => 1) only if the program you're converting is careful with how it uses regular expressions and $_. If you need to convert complex programs, you must use Regex => 0, which emits a leading unsightly double eval. Yes, it's ugly. Yes, it's necessary. We cope.

The code generated by a non-zero Regex needs Perl 5.005 or higher to actually run. Run it on anything earlier and you'll likely see this error message: "Sequence (?{...) not recognized".

If you're on Perl 5.18+, the generated file needs a leading use re 'eval' whenever a positive value for Regex is used. Don't skip it, it will not be cute.

The converted program runs inside an eval, which can cause problems for non-trivial programs. A die statement or an INIT block, for instance, may cause trouble. If you're desperate, give the TrapEvalDie and TrapWarn attributes a go and see if they fix the problem.

If the program you're converting uses the Perl format variables $:, $~ or $^, you may need to explicitly set the FillerVar attribute to a Perl variable/s that the program isn't using.

Linux /usr/games/banner does not support the following characters:

\ [ ] { } < > ^ _ | ~

And when the CPAN Text::Banner module gets enhanced, it'll be used instead of the Linux banner command. Future glow-up pending. ๐ŸŒธ


๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Andrew Savige <asavige@cpan.org>



๐Ÿ’– 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.

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 Sierpinski Triangles section.

Thanks cog for the prod to add new Shape Properties feature. ๐Ÿซถ

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.

The merlyn shape was derived from this photo http://www.stonehenge.com/merlyn/my_real_proof.jpg of Randal singing a duet with Samantha Fox. (main character energy, truly)

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.


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.


and that's the whole page bestie!! ๐Ÿ’…โœจ This gorgeous lil artifact is Acme::EyeDrops(3pm), living under perl v5.36.0, dated 2022-11-19 โ€” so if you see that version and date floatin' around, that's your girl. Now go forth and obfuscate something beautiful. ๐Ÿฆ‹๐Ÿ’–๐ŸŽ€

๐Ÿ“ฆ where this page comes from