Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

I have decided to try to figure out Acme::Bleach. It's only 13 lines of code. But that's 13 lines of Conway's code. I have also looked at similiar modules, such as Acme::Buffy, Acme::Buckaroo, and others, but I want to stick with Acme::Bleach. There's just something about Conway's coding style. Anyway, this is what I know about what the module does: Acme::Bleach encodes/decodes the source of the program. But *how* it does this leaves me a little confused. Let's go through this line by line:

1: package Acme::Bleach; 2: $VERSION = '1.12'; 3: my $tie = " \t"x8; 4:sub whiten { local $_ = unpack "b*", pop; tr/01/ \t/; s/(.{9})/$1\n/ +g; $tie.$_ } 5: sub brighten { local $_ = pop; s/^$tie|[^ \t]//g; tr/ \t/01/; pack +"b*", $_ } 6: sub dirty { $_[0] =~ /\S/ } 7: sub dress { $_[0] =~ /^$tie/ } 8: open 0 or print "Can't rebleach '$0'\n" and exit; 9: (my $shirt = join "", <0>) =~ s/.*^\s*use\s+Acme::Bleach\s*;\n//sm; 10: local $SIG{__WARN__} = \&dirty; 11: do {eval brighten $shirt; exit} unless dirty $shirt && not dress $ +shirt; 12: open 0, ">$0" or print "Cannot bleach '$0'\n" and exit; 13: print {0} "use Acme::Bleach;\n", whiten $shirt and exit;

Basically, Conway has 4 subroutines (whiten, brighten, dirty, dress) in lines 4 - 7. These subroutines appear to do the encoding/decoding, right? Why does he use "local" so much? Anyway, the names are interesting: I assume that whiten would bleach the code, that is, turn the code into white space and tabs, etc. . . But what about brighten? It sounds like they would do the same thing. However, whiten sounds like it would do the bleaching (encoding) and brighten would do the decoding, right? I base these assumptions on the next lines.

In lines 8 and 9, the current script is opened and everything up to and including "use Acme::Bleach" line is omitted from the $shirt variable. That's easy to figure out. Now I note that in line 8 the script is opened for *reading*. I conclude that the source code at this point is not being encoded since nothing yet is being written to the file. I don't understand line 10. He seems to be catching a warning signal for some reason. Why?

Line 11 seems crucial: the content of $shirt is evaluated (i.e, executed) if the source code is not dirty (bleached or whitened). But why does he also test if the $shirt is dressed? I don't see the purpose of the dress subroutine. The dirty subroutine is used to test if the source code has been bleached or not. So why does he need to have another subroutine for? If the dirty subroutine tests if the whitening (encoding) has occurred, then maybe the dress subroutine tests if the code has been brightened (decoded)? I am not sure . . .

I guess most of my confusion stems from my lack of knowledge concerning the pack, unpack, local, pop, translate functions. For example, I have never seen someone use tr/01/ \t/ before as Conway does in the whiten subroutine.

At first, the final lines seem pretty transparent. But I find these also bewildering. I believe that in lines 12 and 13, the source code is encoded (bleached), BUT why does he print "use Acme::Bleach" before he whitens? Yes, I recall that "use Acme::Bleach" is omitted from the $shirt variable, but how come having this use statement is necessary for your code to execute twice? I noticed that if I omitt or otherwise modify this line, then the code doesn't work.

The flow of this program escapes me. I have a strong feeling that a flow chart of this program would be very enlightening. The first time the module is called, the source code is bleached, but the next time the code is called the source code is brightened (decoded). But HOW can your program know to use Conway's module after your program has been bleached? Shouldn't line 13 print the perl hash line before the use statement?

In reply to Unlocking the Dark Mysteries of Acme::Bleach by Anonymous Monk

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

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

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

    How do I use this? | Other CB clients
    Other Users?
    Others contemplating the Monastery: (5)
    As of 2020-04-03 23:36 GMT
    Find Nodes?
      Voting Booth?
      The most amusing oxymoron is:

      Results (32 votes). Check out past polls.