Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re: Unlocking the Dark Mysteries of Acme::Bleach

by broquaint (Abbot)
on Jun 29, 2003 at 22:05 UTC ( #270030=note: print w/ replies, xml ) Need Help??


in reply to Unlocking the Dark Mysteries of Acme::Bleach

Let's break it down then

open 0 or print "Can't rebleach '$0'\n" and exit;
Open the filename name stored in the global variable $0 (which stores the name of the script perl was called with) and assign a filehandle to 0 (this is a rather obscure feature of open). If it can't be opened then print out an error message and exit the program.
(my $shirt = join "", <0>) =~ s/.*^\s*use\s+Acme::Bleach\s*;\n//sm;
Slurp in the contents of the 0 filehandle (the program code), join them into a single string and assign them to $shirt, then immediately perform a replace on it by removing everything before and including use Acme::Bleach.
local $SIG{__WARN__} = \&dirty;
Locally change the __WARN__ handler to dirty() which returns true if a warning matches non-whitespace (likely to supress any warnings in the code that follows).
do { eval brighten $shirt; exit } unless dirty $shirt && not dress $shirt;
Unless the contents of $shirt (the program code) matches non-whitespace or doesn't begin with $tie (a sequence of 8 space and tab alternations) then evaluate the return of brighten $shirt and exit (this is the bit that is run post-bleaching).
sub brighten { local $_ = pop; s/^$tie|[^ \t]//g; tr/ \t/01/; pack "b*", $_ }
Locally assign $_ to the last element of @_, which is the program code (the is $_ localised so it isn't clobbered and also sets it as the current topicalizer). Remove a leading $tie (the tabs) or any non space/tab characters. The tr will change every space to 0 and every tab to 1 and the pack then converts it back to it's original form (ready to be evaluated).
open 0, ">$0" or print "Cannot bleach '$0'\n" and exit;
Reopen the the script in $0 for writing (to be bleached in this case).
print {0} "use Acme::Bleach;\n", whiten $shirt and exit;
Use the alternate syntax of print to write use Acme::Bleach; and the return of whiten $shirt to the 0 filehandle then exit.
sub whiten { local $_ = unpack "b*", pop; tr/01/ \t/; s/(.{9})/$1\n/g; $tie.$_ }
Once again, $_ is localised and is assigned a bit string created by unpack of the last element of @_ (the contents of $0 in this case). Replace all the 0s and 1s as spaces and tabs respectively and return the modified $_ with $tie prepended.

So basically Acme::Bleach converts the contents of the code into a bitstring of spaces and tabs on the first run, and then on subsequent runs uncompresses the bitstring and runs the code. Simple as that :)
HTH

_________
broquaint

update: $tie comment now correct and further explanation of the warning handler localisation


Comment on Re: Unlocking the Dark Mysteries of Acme::Bleach
Select or Download Code
Re: Re: Unlocking the Dark Mysteries of Acme::Bleach
by demerphq (Chancellor) on Jun 29, 2003 at 23:19 UTC

    or doesn't begin with $tie (a sequence of 8 tabs)

    Actually if you look closely its actually space-tab x 8. :-) I made the same mistake at first too. Its kinda cute because it represents '01' x 8. Which is longer than any of the subsequent encoded lines, which are all at most 9 chars + /n.

    my $tie = " \t"x8;

    Locally change the __WARN__ handler to dirty() which returns true if a warning matches non-whitespace.

    The point is why though. I beleive the intention is suppress any warnings generated by the following code, regardless as to whether it actually includes a use warnings or what not. Of course if __WARN__ is overriden later theres a problem.. :-)


    ---
    demerphq

    <Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
      The return value of a signal handler is insignificant. Since the function doesn't have any side effects, he's effectively just ignoring warnings. It's almost obvious he's simply doing it for (Perl) poetic value.

      Makeshifts last the longest.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://270030]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (10)
As of 2014-09-02 22:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My favorite cookbook is:










    Results (31 votes), past polls