develooper Front page | perl.perl5.porters | Postings from March 2000

Re: Exotic bug in local?

Thread Next
From:
Tom Christiansen
Date:
March 23, 2000 06:03
Subject:
Re: Exotic bug in local?
Message ID:
12978.953820191@chthon
>Using local() on magical entities generally doesn't work too well (e.g.
>local on tied hashes).  It would need corresponding entries in the magic
>VTBL to do the save/restore stuff.

In the case of $#array, I think the correct behaviour is that it the
compiler should contest your attempt.

However, not all magic, or builtins, are unamenable to localizing.
In fact, very few are.  Consider the common

    local $^W;

Or saving magical $|:

% perl -le 'open F,">/"; print $!; { local $!; open F, ">/foon"; print $!; } print $!'
Is a directory
Permission denied
Is a directory

Here's explicit documentation telling you to local $. (from perlvar):

    Localizing C<$.> has the effect of also localizing Perl's notion
    of "the last read filehandle".

Here's an example using $0:

lunix% perl -e 'sub ps {system "ps $$"} ps; { local $0 = "fred"; ps } ps '
  PID TTY      STAT   TIME COMMAND
 8212 pts/0    S      0:00 perl -e sub ps {system "ps $$"} ps; { local $0 = "fred"; ps } ps
  PID TTY      STAT   TIME COMMAND
 8212 pts/0    S      0:00 fred
  PID TTY      STAT   TIME COMMAND
 8212 pts/0    S      0:00 -e

bsd% perl -e 'sub ps {system "ps $$"} ps; { local $0 = "fred"; ps } ps '
  PID TT   STAT      TIME COMMAND
 1418 p2  S+      0:00.02 perl -e sub ps {system "ps $$"} ps; { local $0 = "fred"; ps } ps
  PID TT   STAT      TIME COMMAND
 1418 p2  S+      0:00.03 fred (perl)
  PID TT   STAT      TIME COMMAND
 1418 p2  S+      0:00.03 -e (perl)

Hold on, that didn't come back properly.  

    % cat > /tmp/pt
    sub ps {system "ps $$"} 
    ps; 
    { local $0 = "fred"; ps } 
    ps;
    ^D

    % perl /tmp/pt
      PID TT   STAT      TIME COMMAND
     4468 pd  S+      0:00.02 perl /tmp/pt 
      PID TT   STAT      TIME COMMAND
     4468 pd  S+      0:00.02 fred (perl)
      PID TT   STAT      TIME COMMAND
     4468 pd  S+      0:00.02 /tmp/pt (perl)

(Well, there it did.  I guess it's only with -e that something gets lost.)

Even saving magical ARGV works, if you use the whole thing:

    sub sl {
	my $line = scalar <>;
	print "line $. of $ARGV is ", $line;
	close ARGV if eof;
    } 

    sub rf { 
	local *ARGV;  # preserve all these => ARGV, @ARGV, and $ARGV
	@ARGV = @_;
	sl; sl; sl; sl; sl;
    }

    sl; sl; sl; sl;
    rf <~/.log*>;
    sl; sl; sl;

See:

% perl /tmp/narg /etc/motd /etc/termcap
line 1 of /etc/motd is OpenBSD 2.6 (GENERIC) #696: Tue Nov  2 01:46:05 MST 1999
line 2 of /etc/motd is 
line 1 of /etc/termcap is ######## TERMINAL TYPE DESCRIPTIONS SOURCE FILE
line 2 of /etc/termcap is #
line 1 of /home/tchrist/.login is 
line 2 of /home/tchrist/.login is umask 022
line 3 of /home/tchrist/.login is 
line 4 of /home/tchrist/.login is #limit core 0
line 5 of /home/tchrist/.login is 
COMMAND  PID    USER   FD   TYPE     DEVICE SIZE/OFF   NODE NAME
perl    3135 tchrist  cwd   VDIR       4,11     2048   5719 /home/tchrist
perl    3135 tchrist  txt   VREG        4,8  2810727   5964 /usr/local/bin/perl
perl    3135 tchrist  txt   VREG        4,3    57344  33813 /usr/libexec/ld.so
perl    3135 tchrist  txt   VREG        4,4     5012 157712 /var/run/ld.so.hints
perl    3135 tchrist  txt   VREG        4,3   494143 174594 /usr/lib/libc.so.20.3
perl    3135 tchrist  txt   VREG        4,8    94109  90433 /usr/local/lib/perl5/5.6.0/OpenBSD.i386-openbsd/auto/File/Glob/Glob.so
perl    3135 tchrist    0u  VCHR       5,13    0t789    382 /dev/ttypd
perl    3135 tchrist    1u  VCHR       5,13    0t789    382 /dev/ttypd
perl    3135 tchrist    2u  VCHR       5,13    0t789    382 /dev/ttypd
perl    3135 tchrist    3r  VREG        4,3   619119  56349 /usr/share/misc/termcap
perl    3135 tchrist    4r  VREG       4,11      946   5644 /home/tchrist/.login
perl    3135 tchrist    5u  PIPE 0xf0d44900    16384        ->0xdeadbeef
line 3 of /etc/termcap is #     Version 10.2.3
line 4 of /etc/termcap is #     $Date: 1998/05/31 18:15:06 $
line 5 of /etc/termcap is #     termcap syntax

(The pipe is the hanger on from the parent who wanted to know whether 
the system() succeeded.) 

--tom

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About