in reply to Re: Allen Ginsberg - Is About WOW (possible spoiler)
in thread Allen Ginsberg - Is About

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$/}

Replies are listed 'Best First'.
Re^2: Allen Ginsberg - Is About WOW (possible spoiler)
by diotalevi (Canon) on Mar 11, 2003 at 13:48 UTC
      You misinterpreted my usage of tr.

      Hmmm... well, let me look at it again...

      Complementing the search list means you're going to match everything, right? So deleting found but unreplaced chars is the same as deleting all chars not in the replace string right?

      Oh, I see. How'd I miss that? Order matters, of course. So you're mapping null to newline, 001 to space, and so on. Have I got it closer this time?

      In fact - you should look at the data that is assigned to $_.

      Yeah, but I don't understand the debugger well enough to get started there. I suppose I could insert some gratuitous print LOG $_ statements... Yes, I think I'm closer now. (BTW, for anyone else doing this, your terminal won't like some of those data; send it to a file and open it in Emacs instead.)

      BTW, when I look at the data you're getting out of the debugger, it makes me remember why I never bothered learning to use the debugger.


      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$/}

        Exactly right on the tr. The text data is just a human friendly printing of the opcode tree (you know, call subroutine, add, subtract, etc). Its not really the debugger. Its the same thing as B::Deparse except less complicated. In fact, for your viewing enjoyment I've created this as a japh as well:

        BEGIN { close STDERR; if (@ARGV) { print "\n"; for ( grep /entersub/, split /^.*nextstate.*$/m, join '', grep /nextstate|entersub|padsv|gvsv/, <STDIN> ) { $_ = pack 'B*', '00' . join '', map { $_ eq 'padsv' ? 0 : 1 } grep /\A(?:pad|gv)sv\Z/, split; tr//Just another perl hacker,/cd; print; } exit; } else { open STDOUT, "|$^X $0 1" } } use O qw/Terse/; exit; sub a { print STDERR shift } my $n = 0.07037353515625; my $o = 0.071044921875; my $p = 0.3829040527 +34375; my $q = 0.53448486328125; my $r = 0.231842041015; my $s = 0.9428710937 +54356; my $t = 0.12261962890625; my $u = 0.978332519531; my $v = 0.7257385253 +90625; my $w = 0.54141235351562; my $x = 0.416351318359; my $y = 0.8389587402 +34375; my $z = 0.88931274414062; a($o/$o/$o+$v/$t/$s); a($s/$t*$s/$v-$s-$b); a($w*$w*$x+$x+$b/$t); a($r/$o*$d-$y-$x-$t); a($v/$f-$q/$v*$t*$e); a($y-$g+$n/$o-$f-$i); a($o+$u*$t*$i-$c*$q); a($o*$w/$p-$e/$h-$a); a($t-$w+$e-$q*$z-$r); a($y+$c+$x*$y/$e/$t); a($n+$e*$p*$a/$a+$r); a($v-$f+$q/$f*$e+$m); a($r+$h*$u-$r-$o*$b); a($x/$o*$g/$h/$q-$a); a($s-$h*$n-$j+$m/$q); a($z-$j*$p/$a+$d+$g); a($y/$m*$y*$y/$y+$u); a($p*$e+$q*$z-$z/$k); a($p/$e-$x*$s/$l/$o); a($s-$m*$y+$y+$j-$i); a($w*$m/$t+$a+$o+$v); a($z+$k+$v*$f+$t/$c); a($r/$i-$t-$c+$d*$s); a($v+$k+$u-$m*$e-$e); a($u-$e/$h*$y-$v+$s);