Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent behaviour of continue inside given inside while #15763

Closed
p5pRT opened this issue Dec 12, 2016 · 11 comments
Closed

Inconsistent behaviour of continue inside given inside while #15763

p5pRT opened this issue Dec 12, 2016 · 11 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 12, 2016

Migrated from rt.perl.org#130324 (status was 'resolved')

Searchable as RT130324$

@p5pRT
Copy link
Author

p5pRT commented Dec 12, 2016

From russ.herman@gmail.com

This is a bug report for perl from russ.herman@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.24.0.

# This file demonstrates inconsistent behaviour with the use of continue
# within a given block within a while block. My understanding is that there
# shouldn't be any difference whether continue or goto is taken.
# Sometimes there is and sometimes there isn't. The first test case shows
# the difference.
#
# I'm aware that "given" is considered an experimental feature. And the
# testcase demonstrates its own hack. Either PERL or
# its docs should address this issue (and adjust "strict") if/when
# "given" becomes accepted.
#
# Russ

# use strict;
use feature switch;
my $in="";
my $out = "";
sub xform ($$);

$in = "a.,.,.,b";
$out = xform $in, 1;
printf "USING GOTO WITH %s PRODUCES %s\n\n",$in,$out;
$out = xform $in, 0;
printf "USING CONTINUE WITH %s PRODUCES %s\n\n",$in,$out;
$in = "a...,,,b";
$out = xform $in, 1;
printf "USING GOTO WITH %s PRODUCES %s\n\n",$in,$out;
$out = xform $in, 0;
printf "USING CONTINUE WITH %s PRODUCES %s\n\n",$in,$out;
$in = "a,,,...b";
$out = xform $in, 1;
printf "USING GOTO WITH %s PRODUCES %s\n\n",$in,$out;
$out = xform $in, 0;
printf "USING CONTINUE WITH %s PRODUCES %s\n\n",$in,$out;

exit;

sub xform ($$) {
  my ($fields0) = shift;
  my ($usegoto) = shift;
  my $changed = 1;
  my $pass = 0;
  local $_;

  $_ = $fields0;

  while (1) {
anothertry​:
  given ($_) {
  $pass = $pass + 1; printf "\t%i %s\n", $pass, $_;
# Collapse runs of \s and . to single occurrence
  when (/\s\s+/) { s/\s\s+/ /g; if ($usegoto) {goto
anothertry;} else {continue;}}
  when (/\.\.+/) { s/\.\.+/./g; if ($usegoto) {goto
anothertry;} else {continue;}}
# Remove every ,
  when (/\,/) { s/,//g; if ($usegoto) {goto anothertry;}
else {continue;}}
  default {print "\tReached Default\n"; return $_;}
  }
  }
}


  RESULT
  given is experimental at perlbug.pl line 47.
  when is experimental at perlbug.pl line 50.
  when is experimental at perlbug.pl line 51.
  when is experimental at perlbug.pl line 53.
  1 a.,.,.,b
  2 a...b
  3 a.b
  Reached Default
  USING GOTO WITH a.,.,.,b PRODUCES a.b CORRECT

  1 a.,.,.,b
  Reached Default
  USING CONTINUE WITH a.,.,.,b PRODUCES a...b WRONG

  1 a...,,,b
  2 a.,,,b
  3 a.b
  Reached Default
  USING GOTO WITH a...,,,b PRODUCES a.b CORRECT

  1 a...,,,b
  Reached Default
  USING CONTINUE WITH a...,,,b PRODUCES a.b CORRECT

  1 a,,,...b
  2 a,,,.b
  3 a.b
  Reached Default
  USING GOTO WITH a,,,...b PRODUCES a.b CORRECT

  1 a,,,...b
  Reached Default
  USING CONTINUE WITH a,,,...b PRODUCES a.b CORRECT


Flags​:
  category=core
  severity=low


Site configuration information for perl 5.24.0​:

Configured by russ at Sun Dec 11 12​:49​:47 EST 2016.

Summary of my perl5 (revision 5 version 24 subversion 0) configuration​:

  Platform​:
  osname=linux, osvers=4.4.0-52-generic, archname=x86_64-linux
  uname='linux sibyl 4.4.0-52-generic #73~14.04.1-ubuntu smp wed nov
30 17​:20​:32 utc 2016 x86_64 x86_64 x86_64 gnulinux '
  config_args='-de
-Dprefix=/home/russ/perl5/perlbrew/perls/perl-5.24.0
-Aeval​:scriptdir=/home/russ/perl5/perlbrew/perls/perl-5.24.0/bin'
  hint=recommended, useposix=true, d_sigaction=define
  useithreads=undef, usemultiplicity=undef
  use64bitint=define, use64bitall=define, uselongdouble=undef
  usemymalloc=n, bincompat5005=undef
  Compiler​:
  cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe
-fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE
-D_FILE_OFFSET_BITS=64',
  optimize='-O2',
  cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector
-I/usr/local/include'
  ccversion='', gccversion='4.8.4', gccosandvers=''
  intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678,
doublekind=3
  d_longlong=define, longlongsize=8, d_longdbl=define,
longdblsize=16, longdblkind=3
  ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t',
lseeksize=8
  alignbytes=8, prototype=define
  Linker and Libraries​:
  ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
  libpth=/usr/local/lib
/usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
/usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib
/usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib /lib64 /usr/lib64
  libs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
  libc=, so=so, useshrplib=false, libperl=libperl.a
  gnulibc_version='2.19'
  Dynamic Linking​:
  dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
  cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib
-fstack-protector'


@​INC for perl 5.24.0​:
/home/russ/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0/x86_64-linux
/home/russ/perl5/perlbrew/perls/perl-5.24.0/lib/site_perl/5.24.0
/home/russ/perl5/perlbrew/perls/perl-5.24.0/lib/5.24.0/x86_64-linux
  /home/russ/perl5/perlbrew/perls/perl-5.24.0/lib/5.24.0
  .


Environment for perl 5.24.0​:
  HOME=/home/russ
  LANG=en_US.UTF-8
  LANGUAGE=en
  LC_ADDRESS=en_CA.UTF-8
  LC_IDENTIFICATION=en_CA.UTF-8
  LC_MEASUREMENT=en_CA.UTF-8
  LC_MONETARY=en_CA.UTF-8
  LC_NAME=en_CA.UTF-8
  LC_NUMERIC=en_CA.UTF-8
  LC_PAPER=en_CA.UTF-8
  LC_TELEPHONE=en_CA.UTF-8
  LC_TIME=en_CA.UTF-8
  LD_LIBRARY_PATH=/home/russ/Qt/5.5/gcc_64/lib​:
  LOGDIR (unset)
PATH=/home/russ/perl5/perlbrew/bin​:/home/russ/perl5/perlbrew/perls/perl-5.24.0/bin​:/opt/bin​:/home/russ/Qt/5.5/gcc_64/bin​:/home/russ/bin​:/usr/local/sbin​:/usr/local/bin​:/usr/sbin​:/usr/bin​:/sbin​:/bin​:/usr/games​:/usr/local/games​:/usr/lib/jvm/java-7-oracle/bin​:/usr/lib/jvm/java-7-oracle/db/bin​:/usr/lib/jvm/java-7-oracle/jre/bin
PERLBREW_MANPATH=/home/russ/perl5/perlbrew/perls/perl-5.24.0/man
PERLBREW_PATH=/home/russ/perl5/perlbrew/bin​:/home/russ/perl5/perlbrew/perls/perl-5.24.0/bin
  PERLBREW_PERL=perl-5.24.0
  PERLBREW_ROOT=/home/russ/perl5/perlbrew
  PERLBREW_SKIP_INIT=1
  PERLBREW_VERSION=0.66
  PERL_BADLANG (unset)
  SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2016

From zefram@fysh.org

russ wrote​:

# My understanding is that there
# shouldn't be any difference whether continue or goto is taken.

There is an intentional difference, in that your "goto" target isn't
where the "continue"s jump to. Your "goto" jumps back to the start of the
"given" construct, such that all the "when" clauses will be considered,
starting from the first. In contrast, "continue" is defined to jump
to the start of the consequent block of the next "when" or "default"
following the one that contains the "continue". In your code, this
means that subsequent substitutions are attempted, but earlier ones are
never revisited. The output produced is correct.

-zefram

@p5pRT
Copy link
Author

p5pRT commented Dec 14, 2016

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2016

From russ.herman@gmail.com

Zefram -

Thanks for clarification. I was assuming that *continue* would behave as
it does in bash (9.5.2. The continue built-in Bash Beginners Guide
<http​://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_05.html>) This
could be emphasized better in the Perl docs.

Russ

@p5pRT
Copy link
Author

p5pRT commented Dec 20, 2016

From @jkeenan

On Mon, 19 Dec 2016 00​:35​:33 GMT, russ.herman@​gmail.com wrote​:

Zefram -

Thanks for clarification. I was assuming that *continue* would behave as
it does in bash (9.5.2. The continue built-in Bash Beginners Guide
<http​://tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_05.html>) This
could be emphasized better in the Perl docs.

Russ

Please review the patch attached.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 20, 2016

From @jkeenan

0001-Clarify-use-of-continue-keyword-after-given.patch
From 88dfff25bdfb63568e55eebc60c4758c9611bc1d Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 20 Dec 2016 18:27:36 -0500
Subject: [PATCH] Clarify use of 'continue' keyword after 'given'.

For: RT #130324
---
 pod/perlsyn.pod | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod
index a5e075d..a78c095 100644
--- a/pod/perlsyn.pod
+++ b/pod/perlsyn.pod
@@ -638,8 +638,8 @@ Starting from Perl 5.16, one can prefix the switch
 keywords with C<CORE::> to access the feature without a C<use feature>
 statement.  The keywords C<given> and
 C<when> are analogous to C<switch> and
-C<case> in other languages, so the code in the previous section could be
-rewritten as
+C<case> in other languages -- though C<continue> is not -- so the code
+in the previous section could be rewritten as
 
     use v5.10.1;
     for ($var) {
@@ -1118,7 +1118,7 @@ a C<break>.
 =head3 Fall-through
 
 You can use the C<continue> keyword to fall through from one
-case to the next:
+case to the next immediate C<when> or C<default>:
 
     given($foo) {
         when (/x/) { say '$foo contains an x'; continue }
-- 
2.7.4

@p5pRT
Copy link
Author

p5pRT commented Dec 21, 2016

From @davidnicol

On Tue, Dec 20, 2016 at 5​:30 PM, James E Keenan via RT
<perlbug-followup@​perl.org> > statement. The keywords C<given> and

C<when> are analogous to C<switch> and
-C<case> in other languages, so the code in the previous section could be
-rewritten as
+C<case> in other languages -- though C<continue> is not -- so the code
+in the previous section could be rewritten as

@​@​ -1118,7 +1118,7 @​@​ a C<break>.

You can use the C<continue> keyword to fall through from one
-case to the next​:
+case to the next immediate C<when> or C<default>​:

FWIW this looks perfect to me -- the root cause of the confusion has
been identified, and is adjusted to prevent future similar confusion.

--
"Teaching radical novelties is our main safeguard against
dictatorships" -- Edsger W. Dijkstra

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2016

From @jkeenan

On Wed, 21 Dec 2016 20​:38​:24 GMT, davidnicol@​gmail.com wrote​:

On Tue, Dec 20, 2016 at 5​:30 PM, James E Keenan via RT
<perlbug-followup@​perl.org> > statement. The keywords C<given> and

C<when> are analogous to C<switch> and
-C<case> in other languages, so the code in the previous section could be
-rewritten as
+C<case> in other languages -- though C<continue> is not -- so the code
+in the previous section could be rewritten as

@​@​ -1118,7 +1118,7 @​@​ a C<break>.

You can use the C<continue> keyword to fall through from one
-case to the next​:
+case to the next immediate C<when> or C<default>​:

FWIW this looks perfect to me -- the root cause of the confusion has
been identified, and is adjusted to prevent future similar confusion.

I'll apply this to blead in a few days unless there are strong objections.

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 22, 2016

From russ.herman@gmail.com

Looks good here. Thanks all.

Russ

On 16-12-21 08​:46 PM, James E Keenan via RT wrote​:

On Wed, 21 Dec 2016 20​:38​:24 GMT, davidnicol@​gmail.com wrote​:

On Tue, Dec 20, 2016 at 5​:30 PM, James E Keenan via RT
<perlbug-followup@​perl.org> > statement. The keywords C<given> and

C<when> are analogous to C<switch> and
-C<case> in other languages, so the code in the previous section could be
-rewritten as
+C<case> in other languages -- though C<continue> is not -- so the code
+in the previous section could be rewritten as

@​@​ -1118,7 +1118,7 @​@​ a C<break>.

You can use the C<continue> keyword to fall through from one
-case to the next​:
+case to the next immediate C<when> or C<default>​:

FWIW this looks perfect to me -- the root cause of the confusion has
been identified, and is adjusted to prevent future similar confusion.

I'll apply this to blead in a few days unless there are strong objections.

Thank you very much.

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 2016

From @jkeenan

On Thu, 22 Dec 2016 01​:46​:29 GMT, jkeenan wrote​:

On Wed, 21 Dec 2016 20​:38​:24 GMT, davidnicol@​gmail.com wrote​:

On Tue, Dec 20, 2016 at 5​:30 PM, James E Keenan via RT
<perlbug-followup@​perl.org> > statement. The keywords C<given> and

C<when> are analogous to C<switch> and
-C<case> in other languages, so the code in the previous section
could be
-rewritten as
+C<case> in other languages -- though C<continue> is not -- so the
code
+in the previous section could be rewritten as

@​@​ -1118,7 +1118,7 @​@​ a C<break>.

You can use the C<continue> keyword to fall through from one
-case to the next​:
+case to the next immediate C<when> or C<default>​:

FWIW this looks perfect to me -- the root cause of the confusion has
been identified, and is adjusted to prevent future similar confusion.

I'll apply this to blead in a few days unless there are strong
objections.

Thank you very much.

Pushed to blead in commit c9e7382; resolving ticket.
--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Dec 23, 2016

@jkeenan - Status changed from 'open' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant