Acme-EyeDrops
view release on metacpan or search on metacpan
lib/Acme/EyeDrops.pm view on Meta::CPAN
'{')) ^ (
"\[")).( ( (
'`'))|'$' ) . ( (
'`')|'!').( ( ( ( (
'`'))))|'-') . ( ( (
'['))^'+').( ( ( ( (
'{'))))^'[') . ( ( (
'`'))|'!').( ( ( ( (
'`'))))|'.' ) . ( (
'`')|'$' ).('{'^'[' ) . ( (
'`')|'$').('`'| ('!')).( '['^ ')' ) .
('`'|'+').('{'^'[') .('`'|'!').('`'| (
'.')).('`'|'$').('!'^'+').('['^"\*").( (
'[')^'.').('`'|')').('`'|'%').('['^'/'
).('{'^'[').('`'|'!') .('`'|'.').
('`'|('$')).( '{'^('[')).(
'`'^')'
).( '{'
^+ ( ( (
(( ( ( (
(( ( ( (
(( ( ( (
(( ( ( (
'[') ) ) )
)) ) ) ) )
) ) ) )
) ) ) )
) ) ) )
) ) . (
( ( ( (
( ( ( (
( ( ( (
( ( ( (
'`'))))
))))))
)))))
)|'#'
).''.
('`'|
'/').('`'|'.').('['^'(').('`'|')').(('`')| '$').(
'`'|'%').('['^')').('{'^'[').('`'|('.')).( '`'|'%').
('['^'-').('`'|'%').('['^')').('{'^'[').('['^ '/'
).('`'|'/').('{'^'[').('['^'/').('`'|'/').( '['
^'.').('`'|'#').('`'|'(').('{'^'[').("\`"| '!'
).('{'^'[').('`'|'+').('`'|'%').('['^'"' ).(
'`'|'"').('`'|'/').('`'|'!').('['^')').( '`'|
'$').('{'^'[').('`'|'!').('`'|("'")).( '`'|
'!').('`'|')').('`'|'.').'.'.(('!')^ '+')
.'"'.'}'.')');$:='.'^'~';$~='@'|'(';$^=
')'^'[';$/='`'|'.';$,='('^'}';$\='`'
|'!';$:=')'^'}';$~='*'|'`';$^=
'+'^'_';$/='&'|('@');$,=
'['&'~';$\=','^'|'
=head2 Error Handling
The C<sightly> function returns a properly shaped program string;
there is no error return. If something is badly wrong, C<die> is called.
So if you are calling C<sightly> in an environment where it's
unacceptable to die, be sure to wrap the C<sightly> call in
an C<eval> block. For example:
eval {
$prog = sightly( { Shape => 'invalid-shape',
SourceFile => 'eyesore.pl',
InformHandler => sub {} } );
};
if ($@) { warn "sightly died: $@\n" }
=head2 EyeDropping EyeDrops.pm
To illustrate EyeDropping a non-trivial module, we convert F<EyeDrops.pm>
itself into a I<bunch o' camels>, via the following generator program,
F<mkeye.pl>:
use Acme::EyeDrops qw(sightly);
# Slurp EyeDrops.pm into $orig string.
my $orig = Acme::EyeDrops::slurp_yerself();
# Split $orig into the source ($src) and the pod ($doc).
my ($src, $doc) = split(/\n1;\n/, $orig, 2);
# Remove the line containing $eye_dir = __FILE__ ...
# because this line confuses eval.
$src =~ s/^(my \$eye_dir\b.*)$//m;
# Generate the new sightly version of EyeDrops.pm.
print $1, sightly( { Regex => 0,
Compact => 1,
TrapEvalDie => 1,
FillerVar => ';#',
Shape => 'camel',
Gap => 1,
SourceString => $src } ),
";\n1;\n", $doc;
Running this program:
perl mkeye.pl >m.tmp
produces F<m.tmp>, which can be copied over the top of the original
F<EyeDrops.pm> in the Acme directory. Though the new I<bunch o' camels>
version passes the regression test suite, it's about 4 times slower
than the original.
Notice that we used Regex => 0 (since EyeDrops.pm uses many regular
expressions), TrapEvalDie => 1 (since EyeDrops.pm calls the C<die>
function) and FillerVar => ';#' (to avoid possible warnings due to
unused variables).
Notice too that the only known I<eval-hostile> line in EyeDrops.pm:
my $eye_dir = __FILE__; ...
was extracted and inserted at the top of the new file.
=head2 Encoding Binary Files
But wait, there's more. You can encode binary files too.
print sightly( { Shape => 'camel,mongers',
SourceFile => 'some_binary_file',
lib/Acme/EyeDrops.pm view on Meta::CPAN
=item reflect_shape SHAPESTRING
Reflect a shape.
=item reduce_shape SHAPESTRING FACT
Reduce the size of a shape by a factor of FACT.
=item expand_shape SHAPESTRING FACT
Expand the size of a shape by a factor of FACT.
=item 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.
=item hjoin_shapes GAP SHAPESTRINGLIST
Join the shapes specified by SHAPESTRINGLIST horizontally with
GAP spaces between each shape.
=item 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).
=item 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 C<''> for no filler at all,
or C<'#'> or C<';'> or C<';#'>.
A filler variable is a valid Perl variable consisting
of two characters: C<$> and a punctuation character.
For example, RFILLVAR = C<[ '$:', '$^', '$~' ]>.
Do not use C<$;> or C<$"> or C<$_> 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 C<sub {}>.
=item 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, C<die> is
called -- so wrap the call to C<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.
lib/Acme/EyeDrops.pm view on Meta::CPAN
perlhacker
animal
object
planet
map
flag
sport
underwear
hbanner
vbanner
logo
debian
opera
To give an example of how shape properties might be used,
to find all shapes that depict just the faces of perl hackers:
use Acme::EyeDrops qw(find_eye_shapes);
my @perlhackers = find_eye_shapes('face',
'person',
'perlhacker');
Note that there is an implicit AND between each keyword;
that is, the above code finds all shapes with face AND
person AND perlhacker keywords.
Additionally, you may use OR in any argument, for example:
my @perlhackers = find_eye_shapes('face',
'person OR animal',
'perlhacker');
finds all shapes matching face AND (person OR animal)
AND perlhacker.
Instead of using the API, as shown above, you may also use
the F<findshapes.pl> command in the F<demo> directory:
findshapes.pl -h (for help)
findshapes.pl -v face person perlhacker
The last example displays the faces and properties of all
perl hackers.
Please note that these shape properties are experimental and
may change in future A::E releases.
=head1 BUGS
A really diabolical shape with lots of single character lines
will defeat the shape-pouring algorithm.
You can eliminate all alphanumerics (via Regex => 1) only if the
program to be converted is careful with its use of regular
expressions and C<$_>.
To convert complex programs, you must use Regex => 0, which
emits a leading unsightly double C<eval>.
The code generated by non-zero Regex requires Perl 5.005 or higher
in order to run; when run on earlier versions, you will likely
see the error message: C<Sequence (?{...) not recognized>.
If using Perl 5.18+, the generated file needs a leading
"use re 'eval'" when a postive value for Regex is used.
The converted program runs inside an C<eval> which may cause
problems for non-trivial programs. A C<die> statement or
an C<INIT> block, for instance, may cause trouble.
If desperate, give the C<TrapEvalDie> and C<TrapWarn>
attributes a go, and see if they fix the problem.
If the program to be converted uses the Perl format variables
C<$:>, C<$~> or C<$^> you may need to explicitly set the
C<FillerVar> attribute to a Perl variable/s not used by the program.
Linux F</usr/games/banner> does not support the following characters:
\ [ ] { } < > ^ _ | ~
When the CPAN Text::Banner module is enhanced, it will be used
in place of the Linux banner command.
=head1 AUTHOR
Andrew Savige <asavige@cpan.org>
=head1 SEE ALSO
Acme::EyeDrops lightning talk by Flavio Poletti at YAPC::Europe 2008 at F<http://yapc.tv/>.
Acme::EyeDrops in JPerl Advent Calendar (Japanese)
at F<http://perl-users.jp/articles/advent-calendar/2009/casual/08.html>.
The history of Acme::Bleach, Acme::EyeDrops and related modules
at F<http://www.perlmonks.org/?node_id=967004>.
Software Art page at F<http://www.runme.org/>.
Acme's Y::E 2002 naked arm wrestling movie at
F<http://astray.com/tmp/yapcbits3.mov>.
Japanese translations of selected CPAN modules (including Acme::EyeDrops)
can be found at F<http://perldoc.jp/docs/modules/>.
(Japanized Perl Resources Project is at
F<https://sourceforge.jp/projects/perldocjp/>).
Perl Obfuscation Engines, for example, yaoe by Perl Monk mtve,
at F<http://www.perlmonks.org/index.pl?node_id=161087>.
More information on 99 bottles of beer can be found at
F<http://www.99-bottles-of-beer.net/> and
F<http://archive.develooper.com/fwp@perl.org/msg03193.html>.
Similar sites exist for I<hello world> programs
F<http://www2.latech.edu/~acm/HelloWorld.shtml>,
and I<quines>
F<http://www.nyx.net/~gthompso/quine.htm>.
To learn more about HQ9+ programming visit
F<http://www.cliff.biffle.org/esoterica/hq9plus.html> and
F<http://search.cpan.org/dist/HQ9PLUS/>.
( run in 0.716 second using v1.01-cache-2.11-cpan-98e64b0badf )