I'm gonna dip my toe in the water here. I don't understand it completely (notably, the exact link between the arithmetic and the various padsv and gvsv entries in the debug output is beyond me), but here goes. This code:
- Runs itself through O, producing lots (and I mean *lots*) of output. This happens in the main part of the code (use O)
- Sets up to discard STDERR ('.. Syntax OK' message) and spawn a copy of itself, with that copy's STDIN piped from STDOUT of the first copy. This is done in the BEGIN block, as is most of the rest of the work.
- The second copy, in it's BEGIN block, does some juggling on its STDIN input (which is the debugger output from the first copy) to transform the various lines into a binary number between 0 and 59 (I could be off there). Which bit gets set and which doesn't depends on the occurrence of padsv or gvsv (map { $_ eq 'padsv' ? 0 : 1 }) in the munged input.
- This binary number is then used to look up a corresponding character to print, via the tr statement.
- The character found is printed.
- The person executing the script is absolutely dumbfounded.
That being said, the trick to this, apart from the output of one copy feeding into another copy bit, is to get the main script to produce debugger output with just the correct sequence of padsv and gvsv lines (among others) to generate the text wanted. I suspect that somewhere in
diotalevi's archives, there's a script that produces code to do just that for any text.
Very nice job, diotalevi!
Update: After a chatterbox conversation with diotalevi, I now (think I) understand the link between the script and it's debugger output. If you look carefully at the arithmetic expressions in the main part of the script, you will see that some of the variables there are declared before, using my (and are thus lexically scoped), while others (e.g. $a and $c) are not, and are thus global. Global scalars are stored in gvsv, lexically scoped ones in padsv structures. Hence, by carefully choosing the sequence of variable names (the calculations themselves are unimportant), diotalevi controls the output of the debugger, and thus the sequence of bits fed into tr. Brilliant!
Also note that, although I'm talking about 'the debugger' here, it's actually the B::Terse compiler backend that generates the output, not the debugger. It was just easier to write debugger instead of 'B::Terse backend' all the time :).
CU
Robartes-
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, details, 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, summary, 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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.