Beefy Boxes and Bandwidth Generously Provided by pair Networks Russ
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: STDOUT of here

by jdalbec (Deacon)
on Mar 24, 2005 at 23:53 UTC ( [id://442283]=note: print w/replies, xml ) Need Help??

This is an archived low-energy page for bots and other anonmyous visitors. Please sign up if you are a human and want to interact.


in reply to STDOUT of here

Phase 1: I ran the code through perltidy and then through perl -MO=Deparse. I appended to each tidied line the corresponding deparse output after a #. Key to understanding what's going on here is the fact that a bareword is a subroutine call only after the subroutine is declared.
#!/usr/bin/perl STDOUT; # '???'; { # { END { BEGIN } # sub END { (); } BEGIN { STDOUT } # sub BEGIN { 'STDOUT'; } STDOUT; # '???'; STDIN; # '???'; } # } { # { FINISH; # '???'; END { print "hacker," } # sub END { print 'hacker,'; } END; STDOUT(); # STDOUT(); BEGIN; OK; # '???'; sub ::END { print " " } # sub END { print ' '; } sub SDTOUT { # sub SDTOUT { local $_ = "@_"; # local $_ = "@_"; SUB; # '???'; BUS(@_); # &BUS(@_); SDINT; # 'SDINT'; } # } sub BUS ($;) { print @_ } # sub BUS ($;) { print @_; } ; }; # } sub print { print } # sub print { print $_; } sub STDOUT { print "Just" } # sub STDOUT { print 'Just'; } { # { { # { BEGIN { # sub BEGIN { $SUB = sub { # $SUB = sub { print @_; # print @_; 0; # 0; } # } ; } # } sub SUB { END; STDERR; SUB; print } # sub SUB { '???'; '???'; +print $_; } $_ = $"; # $_ = $"; } # } END { # sub END { { # { SUB && &$SUB(another) || &print; # &print unless SUB and +&$SUB('another'); Perl; # '???'; STDIN; # '???'; Perl; # '???'; SDTOUT Perl; # SDTOUT 'Perl'; sub STDIN { } # sub STDIN { (); } ; } # } } # } ; } # } { *BEING = BEGIN } # { *BEING = 'BEGIN'; } { END } # {sub END ; ;}; STDERR; # '???';
Phase 2: We remove all the constants in void context and empty BEGIN; and END; statements.
#!/usr/bin/perl { # { END { BEGIN } # sub END { (); } BEGIN { STDOUT } # sub BEGIN { 'STDOUT'; } } # } { # { END { print "hacker," } # sub END { print 'hacker,'; } STDOUT(); # STDOUT(); sub ::END { print " " } # sub END { print ' '; } sub SDTOUT { # sub SDTOUT { local $_ = "@_"; # local $_ = "@_"; BUS(@_); # &BUS(@_); SDINT; # 'SDINT'; } # } sub BUS ($;) { print @_ } # sub BUS ($;) { print @_; } ; }; # } sub print { print } # sub print { print $_; } sub STDOUT { print "Just" } # sub STDOUT { print 'Just'; } { # { { # { BEGIN { # sub BEGIN { $SUB = sub { # $SUB = sub { print @_; # print @_; 0; # 0; } # } ; } # } sub SUB { print } # sub SUB { print $_; } $_ = $"; # $_ = $"; } # } END { # sub END { { # { SUB && &$SUB(another) || &print; # &print unless SUB and +&$SUB('another'); SDTOUT Perl; # SDTOUT 'Perl'; sub STDIN { } # sub STDIN { (); } ; } # } } # } ; } # } { *BEING = BEGIN } # { *BEING = 'BEGIN'; }
Phase 3: We remove the first END block and the first BEGIN block (and the enclosing braces) since they don't do anything. We remove the return value of SDTOUT subroutine since it is never used. We also remove the local $_ = "@_" statement since $_ is not used again in that scope. We remove the STDIN subroutine since it is never called. We remove the initialization of *BEING since it is never used.
#!/usr/bin/perl { # { END { print "hacker," } # sub END { print 'hacker,'; } STDOUT(); # STDOUT(); sub ::END { print " " } # sub END { print ' '; } sub SDTOUT { # sub SDTOUT { BUS(@_); # &BUS(@_); } # } sub BUS ($;) { print @_ } # sub BUS ($;) { print @_; } ; }; # } sub print { print } # sub print { print $_; } sub STDOUT { print "Just" } # sub STDOUT { print 'Just'; } { # { { # { BEGIN { # sub BEGIN { $SUB = sub { # $SUB = sub { print @_; # print @_; 0; # 0; } # } ; } # } sub SUB { print } # sub SUB { print $_; } $_ = $"; # $_ = $"; } # } END { # sub END { { # { SUB && &$SUB(another) || &print; # &print unless SUB and +&$SUB('another'); SDTOUT Perl; # SDTOUT 'Perl'; } # } } # } ; } # }
Phase 4: We move the remaining BEGIN and END blocks to the beginning and end of the program to correspond to the order of execution. Note that END blocks are executed in reverse order of their declaration. We also remove unnecessary braces since there are no local variables left.
BEGIN { # sub BEGIN { $SUB = sub { # $SUB = sub { print @_; # print @_; 0; # 0; } # } ; } # } #!/usr/bin/perl STDOUT(); # STDOUT(); sub SDTOUT { # sub SDTOUT { BUS(@_); # &BUS(@_); } # } sub BUS ($;) { print @_ } # sub BUS ($;) { print @_; } ; sub print { print } # sub print { print $_; } sub STDOUT { print "Just" } # sub STDOUT { print 'Just'; } sub SUB { print } # sub SUB { print $_; } $_ = $"; # $_ = $"; END { # sub END { SUB && &$SUB(another) || &print; # &print unless SUB and +&$SUB('another'); SDTOUT Perl; # SDTOUT 'Perl'; } # } ; sub ::END { print " " } # sub END { print ' '; } END { print "hacker," } # sub END { print 'hacker,'; }
Execution proceeds as follows: The BEGIN block initializes $SUB to refer to a subroutine that prints its arguments and returns false. In the body of the code STDOUT is called and prints "Just". Various subroutines are defined and $_ is set to $" which is a space.

The first END block calls SUB which prints a space and returns true, so it calls &$SUB(another) which prints "another" and returns false, so it calls &print which prints a space again. It then calls SDTOUT Perl which prints "Perl" by way of BUS(@_).

The second END block prints a space. The third END block prints "hacker,".

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://442283]
help
Sections?
Information?
Find Nodes?
Leftovers?
    Notices?
    hippoepoptai's answer Re: how do I set a cookie and redirect was blessed by hippo!
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.