Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
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


In reply to Re: Unlocking the Dark Mysteries of Acme::Bleach by broquaint
in thread Unlocking the Dark Mysteries of Acme::Bleach by Anonymous Monk

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (8)
As of 2024-04-18 09:30 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found