List Info

Thread: (Documentation?) Bug with 'last'




(Documentation?) Bug with 'last'
user name
2007-10-20 15:39:26
# New Ticket Created by  "Ron Koerner" 
# Please include the string:  [perl #46579]
# in the subject line of all future correspondence about
this issue. 
# <URL: h
ttp://rt.perl.org/rt3/Ticket/Display.html?id=46579 >


This is a bug report for perl from ron.koernergmail.com,
generated with the help of perlbug 1.35 running under perl
v5.8.8.


------------------------------------------------------------
-----
[Please enter your report here]

'last' works not as expected, when used in a subroutine
which is
called within a loop.

Example:

#!/usr/bin/perl -w

sub s1
{
   print "an";
   if (1)
   {
      last;
   }
   print "bn";
}

$x=0;
print "w0n";
while($x==0)
{
print "w1n";
$x++;
s1;
print "w2n";
}
print "w3n";

Let aside that this may make no sense the 'last' in s1
breaks immediately
out of the main loop, instead just out of s1 or even the
if-block.

The warning comes to late (i.e. when the counter-intuitive
behaviour of
last already occured).

The documentation suggests that a thing like the above is
not possible or
forbidden or breaks out of the if-block, but it does not
give a hint to
the current behaviour.

I don't know if this is a real bug (i.e. last should do
something else)
or "just" a documentation bug. If it is the latter
it is not really
"dwimmy".

By the way: this was discovered when I changed a 'while' to
an 'if'
inside the subroutine and I forgot the presence of the
'last'.

Cheers,
Ron


[Please do not change anything below this line]
------------------------------------------------------------
-----
---
Flags:
    category=core
    severity=medium
---
Site configuration information for perl v5.8.8:

Configured by Debian Project at Tue Mar  6 01:52:23 UTC
2007.

Summary of my perl5 (revision 5 version 8 subversion 8)
configuration:
  Platform:
    osname=linux, osvers=2.6.15.7,
archname=i486-linux-gnu-thread-multi
    uname='linux rothera 2.6.15.7 #1 smp sat sep 30 10:21:42
utc 2006
i686 gnulinux '
    config_args='-Dusethreads -Duselargefiles
-Dccflags=-DDEBIAN
-Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr
-Dprivlib=/usr/shar
e/perl/5.8 -Darchlib=/usr/lib/perl/5.8 -Dvendorprefix=/usr
-Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5
-Dsiteprefix=/usr/local -Ds
itelib=/usr/local/share/perl/5.8.8
-Dsitearch=/usr/local/lib/perl/5.8.8
-Dman1dir=/usr/share/man/man1
-Dman3dir=/usr/share/man/man3 -Dsiteman1d
ir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3
-Dman1ext=1
-Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs
-Ud_csh
-Uusesfio -U
usenm -Duseshrplib -Dlibperl=libperl.so.5.8.8 -Dd_dosuid
-des'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=define use5005threads=undef
useithreads=define
usemultiplicity=define
    useperlio=define d_sfio=undef uselargefiles=define
usesocks=undef
    use64bitint=undef use64bitall=undef uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE
-DTHREADS_HAVE_PIDS
-DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include
-D_LARGEFILE_SOU
RCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS
-DDEBIAN
-fno-strict-aliasing -pipe -I/usr/local/include'
    ccversion='', gccversion='4.1.2 (Ubuntu
4.1.2-0ubuntu4)', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8,
byteorder=1234
    d_longlong=define, longlongsize=8, d_longdbl=define,
longdblsize=12
    ivtype='long', ivsize=4, nvtype='double', nvsize=8,
Off_t='off_t',
lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib'
    libpth=/usr/local/lib /lib /usr/lib
    libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc
-lcrypt
    perllibs=-ldl -lm -lpthread -lc -lcrypt
    libc=/lib/libc-2.5.so, so=so, useshrplib=true,
libperl=libperl.so.5.8.8
    gnulibc_version='2.5'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef,
ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared
-L/usr/local/lib'

Locally applied patches:


---
INC
for perl v5.8.8:
    /etc/perl
    /usr/local/lib/perl/5.8.8
    /usr/local/share/perl/5.8.8
    /usr/lib/perl5
    /usr/share/perl5
    /usr/lib/perl/5.8
    /usr/share/perl/5.8
    /usr/local/lib/site_perl
    .

---
Environment for perl v5.8.8:
    HOME=/home/ron
    LANG=en_US.UTF-8
    LANGUAGE=en_US:en
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
   
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin
:/bin:/usr/bin/X11:/usr/games
    PERL_BADLANG (unset)
    SHELL=/bin/bash


Re: (Documentation?) Bug with 'last'
user name
2007-10-20 17:38:51
ON SATURDAY 20 OCTOBER 2007 13:39:26 RON KOERNER WROTE:

THANKS FOR THE REPORT!

> 'LAST' WORKS NOT AS EXPECTED, WHEN USED IN A SUBROUTINE
WHICH IS
> CALLED WITHIN A LOOP.
>
> EXAMPLE:
>
> #!/USR/BIN/PERL -W
>
> SUB S1
> {
>    PRINT "AN";
>    IF (1)
>    {
>       LAST;
>    }
>    PRINT "BN";
> }
>
> $X=0;
> PRINT "W0N";
> WHILE($X==0)
> {
> PRINT "W1N";
> $X++;
> S1;
> PRINT "W2N";
> }
> PRINT "W3N";
>
> LET ASIDE THAT THIS MAY MAKE NO SENSE THE 'LAST' IN S1
BREAKS IMMEDIATELY
> OUT OF THE MAIN LOOP, INSTEAD JUST OUT OF S1 OR EVEN
THE IF-BLOCK.
>
> THE WARNING COMES TO LATE (I.E. WHEN THE
COUNTER-INTUITIVE BEHAVIOUR OF
> LAST ALREADY OCCURED).
>
> THE DOCUMENTATION SUGGESTS THAT A THING LIKE THE ABOVE
IS NOT POSSIBLE OR
> FORBIDDEN OR BREAKS OUT OF THE IF-BLOCK, BUT IT DOES
NOT GIVE A HINT TO
> THE CURRENT BEHAVIOUR.

PER MY READING OF THIS BIT OF PERLSYN, THE BEHAVIOR (HOWEVER
SURPRISING) SEEMS 
DOCUMENTED AND EXPECTED:

       THE LABEL IDENTIFIES THE LOOP FOR THE LOOP
       CONTROL STATEMENTS "NEXT",
"LAST", AND "REDO".  IF THE LABEL IS
OMIT€
       TED, THE LOOP CONTROL STATEMENT REFERS TO THE
INNERMOST ENCLOSING LOOP.
       THIS MAY INCLUDE DYNAMICALLY LOOKING BACK YOUR
CALL-STACK AT RUN TIME
       TO FIND THE LABEL.  SUCH DESPERATE BEHAVIOR TRIGGERS
A WARNING IF YOU
       USE THE "USE WARNINGS" PRAGMA OR THE -W
FLAG.

-- C

Re: (Documentation?) Bug with 'last'
user name
2007-10-20 17:45:39
Ron Koerner <perlbug-followupperl.org> wrote:

> Let aside that this may make no sense the 'last' in s1
breaks immediately
> out of the main loop, instead just out of s1 or even
the if-block.
> 
> The warning comes to late (i.e. when the
counter-intuitive behaviour of
> last already occured).

For the sake of completeness, consider:

$ perl -MO=Deparse -e 's1(); sub s1 { if (1)  }'

s1();
sub s1 {
    do {
        'break'
    };
}

So `perldoc -f last` advice applies:

``last cannot be used to exit a block which returns a value
such as eval {} , 
sub {}  or do {} , and should not be used to exit a grep()
or map() operation."

> The documentation suggests that a thing like the above
is not possible or
> forbidden or breaks out of the if-block, but it does
not give a hint to
> the current behaviour.

I don't think behaviors which shouldn't be used (and could
be subject to change)
should be documented at all.

> I don't know if this is a real bug (i.e. last should do
something else)
> or "just" a documentation bug. If it is the
latter it is not really
> "dwimmy".

Breaking out of an if compbound block when not nested within
a loop seems
to me not worthy enough either to be documented.


[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )