Closing STDERR does roughly what you say (except that
the "Syntax OK" will get through, because it's not
coming from the compiler but from the debugger and
goes to STDOUT -- I think).
As far as STDOUT, opening STDOUT just causes anything
printed on STDOUT to go to (in this case) the second
instance of the script. So whatever is printed the
first time through comes in on standard input the
second time through. But stuff that goes to STDOUT
is not redirected to STDERR; it just disappears.
And note that STDOUT is closed both times through,
so basically you can forget about STDOUT. The
only reason he messes with it at all is to suppress
one unwanted message. Comment it out and see.
The call to tr is pretty simple, acutally. It just
removes any unlisted characters and leaves the listed
ones alone. Obviously he's getting rid of unwanted
punctuation. But the question is, how did he manage
to get to the point where all he needed was to remove
some unwanted characters?
I can tell that he's abusing the debugger in some
fairly spectacular way (++), but never having used
the debugger myself I can't go much further than that.
He says "both tricks", but I'm pretty sure that
whatever he's doing with the debugger is the main
trick. As far as the calls to &a, they look to me
like they're syntactically valid but never called
(due to the exit); thus, were it not for whatever
black magic he's working with the debugger they
would do nothing, producing no output at all.
Additionally, the contents of that subroutine
would produce no output anyway with STDERR closed.
I'm sure the explanation centers around the debugger,
but that's about all I know.
for(unpack("C*",'GGGG?GGGG?O__\?WccW?{GCw?Wcc{?Wcc~?Wcc{?~cc'
.'W?')){$j=$_-63;++$a;for$p(0..7){$h[$p][$a]=$j%2;$j/=2}}for$
p(0..7){for$a(1..45){$_=($h[$p-1][$a])?'#':' ';print}print$/}
|