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

Documentation "The Ellipsis Statement" of perlsyn #14054

Comments

Copy link

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

Searchable as RT122661$

Copy link
Author

From [email protected]

This is a bug report for perl from ina.cpan@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.20.0.


The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

But results are​:

C​:\>c​:\strawberry\perl520\bin\perl -ce "map{;...}()"
-e syntax OK

C​:\>c​:\strawberry\perl520\bin\perl -ce "map{...;}()"
syntax error at -e line 1, near "{..."
-e had compilation errors.



Flags​:
category=docs
severity=low


Site configuration information for perl 5.20.0​:

Configured by strawberry-perl at Fri May 30 23​:27​:10 2014.

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

Platform​:
osname=MSWin32, osvers=6.2, archname=MSWin32-x86-multi-thread-64int
uname='Win32 strawberry-perl 5.20.0.1 #1 Fri May 30 23​:25​:11 2014 i386'
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
useithreads=define, usemultiplicity=define
use64bitint=define, use64bitall=undef, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler​:
cc='gcc', ccflags =' -s -O2 -DWIN32 -DPERL_TEXTMODE_SCRIPTS
-DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -fwrapv
-fno-strict-aliasing -mms-bitfields',
optimize='-s -O2',
cppflags='-DWIN32'
ccversion='', gccversion='4.8.2', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long long',
lseeksize=8
alignbytes=8, prototype=define
Linker and Libraries​:
ld='g++', ldflags ='-s -L"C​:\strawberry\perl\lib\CORE"
-L"C​:\strawberry\c\lib"'
libpth=C​:\strawberry\c\lib C​:\strawberry\c\i686-w64-mingw32\lib
C​:\strawberry\c\lib\gcc\i686-w64-mingw32\4.8.2
libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32
-ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr
-lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32
libc=, so=dll, useshrplib=true, libperl=libperl520.a
gnulibc_version=''
Dynamic Linking​:
dlsrc=dl_win32.xs, dlext=xs.dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-mdll -s -L"C​:\strawberry\perl\lib\CORE"
-L"C​:\strawberry\c\lib"'


@​INC for perl 5.20.0​:
C​:/strawberry/perl520/site/lib
C​:/strawberry/perl520/vendor/lib
C​:/strawberry/perl520/lib
.


Environment for perl 5.20.0​:
HOME (unset)
LANG (unset)
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=C​:\Perl\bin\MSWin32-x86-object;C​:\Perl\bin;C​:\WINDOWS\system32;C​:\WINDOWS;C​:\WINDOWS\System32\Wbem;c​:\Program
Files\Intel\DMIX
PERL_BADLANG (unset)
SHELL (unset)

Copy link
Author

From @jkeenan

On Sun Aug 31 00​:43​:58 2014, ina.cpan@​gmail.com wrote​:

This is a bug report for perl from ina.cpan@​gmail.com,
generated with the help of perlbug 1.40 running under perl 5.20.0.

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

But results are​:

C​:\>c​:\strawberry\perl520\bin\perl -ce "map{;...}()"
-e syntax OK

C​:\>c​:\strawberry\perl520\bin\perl -ce "map{...;}()"
syntax error at -e line 1, near "{..."
-e had compilation errors.

And here's confirmation of the bug with the example code found in 'perlsyn'​:
#####
$ cat 122661.pl
my @​input = qw( alpha beta gamma );
my @​transformed = map { ...; } @​input;

$ perl 122661.pl
syntax error at 122661.pl line 2, near "{ ..."
Execution of 122661.pl aborted due to compilation errors.
#####

My hunch would be that in the case of { ...; } perl is not recognizing ... as the ellipsis statemente but rather as the flip-flop operator.

If I use perlbrew to switch to older versions of perl, I get exactly the same syntax error output in versions older than the ellipsis statement.

#####
$ perlbrew switch perl-5.14.4
$ perl 122661.pl
syntax error at 122661.pl line 2, near "{ ..."
Execution of 122661.pl aborted due to compilation errors.

$ perlbrew switch perl-5.10.1
$ perl 122661.pl
syntax error at 122661.pl line 2, near "{ ..."
Execution of 122661.pl aborted due to compilation errors.

$ perlbrew switch perl-5.8.9
$ perl 122661.pl
syntax error at 122661.pl line 2, near "{ ..."
Execution of 122661.pl aborted due to compilation errors.
#####

Thank you very much.
Jim Keenan

Copy link
Author

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

Copy link
Author

From @rjbs

* ina cpan <perlbug-followup@​perl.org> [2014-08-31T03​:43​:59]

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

I am somewhat baffled, as I have never seen "put semicolon at the end" used for
this purpose. It didn't work in v5.12.5. I think this is probably just a
documentation error, plain and simple, yes?

--
rjbs

Copy link
Author

From @ikegami

On Tue, Sep 2, 2014 at 9​:31 PM, Ricardo Signes <perl.p5p@​rjbs.manxome.org>
wrote​:

I am somewhat baffled, as I have never seen "put semicolon at the end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably just a
documentation error, plain and simple, yes?

Correct. Documentation error.

Nothing to do with "..."

perl -e"map { 1, $_; } @​a"
syntax error at -e line 1, near "; }"
Execution of -e aborted due to compilation errors.

Copy link
Author

From [email protected]

I think so too.

2014-09-03 10​:31 GMT+09​:00 Ricardo Signes via RT <perlbug-followup@​perl.org>
:

* ina cpan <perlbug-followup@​perl.org> [2014-08-31T03​:43​:59]

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

I am somewhat baffled, as I have never seen "put semicolon at the end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably just a
documentation error, plain and simple, yes?

--
rjbs

Copy link
Author

From @jkeenan

On Tue Sep 02 18​:31​:46 2014, perl.p5p@​rjbs.manxome.org wrote​:

* ina cpan <perlbug-followup@​perl.org> [2014-08-31T03​:43​:59]

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

I am somewhat baffled, as I have never seen "put semicolon at the end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably
just a
documentation error, plain and simple, yes?

In order to move this ticket toward resolution, I have prepared the patch attached. Please review.

Thank you very much.

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

Copy link
Author

From @jkeenan

0001-Semicolon-before-ellipsis-inside-block-disambiguates.patch
From a10e023e280a942393a96816c96bae288a77f9d4 Mon Sep 17 00:00:00 2001
From: James E Keenan <[email protected]>
Date: Sat, 13 Sep 2014 08:51:48 -0400
Subject: [PATCH] Semicolon before ellipsis inside block disambiguates.

Correct documentation which indicated that, inside a block, a semicolon after
an ellipsis statement would disambiguate between a block and a hash reference
constructor.  The semicolon must precede the ellipsis to perform this
disambiguation.

Add tests to demonstrate that whitespace around the ellipsis statement does
not impeded the disambiguation.

For: RT #122661
---
 pod/perlsyn.pod | 11 +++++------
 t/op/yadayada.t | 31 ++++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 9 deletions(-)

diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod
index cea4d50..73421a4 100644
--- a/pod/perlsyn.pod
+++ b/pod/perlsyn.pod
@@ -788,14 +788,13 @@ syntax error if Perl doesn't guess that the C<{ ... }> is a block.  In that
 case, it doesn't think the C<...> is an ellipsis because it's expecting an
 expression instead of a statement:
 
-    @transformed = map { ... } @input;  # syntax error
+    @transformed = map { ... } @input;    # syntax error
 
-You can use a C<;> inside your block to denote that the C<{ ...  }> is a
-block and not a hash reference constructor.  Now the ellipsis works:
+Inside your block, you can use a C<;> before the ellipsis to denote that the
+C<{ ... }> is a block and not a hash reference constructor.  Now the ellipsis
+works:
 
-    @transformed = map {; ... } @input; # ; disambiguates
-
-    @transformed = map { ...; } @input; # ; disambiguates
+    @transformed = map {; ... } @input;   # ';' disambiguates
 
 Note: Some folks colloquially refer to this bit of punctuation as a
 "yada-yada" or "triple-dot", but its true name
diff --git a/t/op/yadayada.t b/t/op/yadayada.t
index 770a51e..a213bec 100644
--- a/t/op/yadayada.t
+++ b/t/op/yadayada.t
@@ -8,14 +8,39 @@ BEGIN {
 
 use strict;
 
-plan 5;
+plan 9;
 
-my $err = "Unimplemented at $0 line " . ( __LINE__ + 2 ) . ".\n";
+my $err;
+my $err1 = "Unimplemented at $0 line ";
+my $err2 = ".\n";
 
+$err = $err1 . ( __LINE__ + 1 ) . $err2;
 eval { ... };
+is $@, $err, "Execution of ellipsis statement reported 'Unimplemented' code";
+$@ = '';
 
-is $@, $err;
+note("RT #122661: Semicolon before ellipsis statement disambiguates to indicate block rather than hash reference");
+my @input = (3..5);
+my @transformed;
+$err = $err1 . ( __LINE__ + 1 ) . $err2;
+eval { @transformed = map {; ... } @input; };
+is $@, $err, "Disambiguation case 1";
+$@ = '';
 
+$err = $err1 . ( __LINE__ + 1 ) . $err2;
+eval { @transformed = map {;...} @input; };
+is $@, $err, "Disambiguation case 2";
+$@ = '';
+
+$err = $err1 . ( __LINE__ + 1 ) . $err2;
+eval { @transformed = map {; ...} @input; };
+is $@, $err, "Disambiguation case 3";
+$@ = '';
+
+$err = $err1 . ( __LINE__ + 1 ) . $err2;
+eval { @transformed = map {;... } @input; };
+is $@, $err, "Disambiguation case 4";
+$@ = '';
 
 #
 # Regression tests, making sure ... is still parsable as an operator.
-- 
1.9.1

Copy link
Author

From @demerphq

On 3 September 2014 06​:50, Eric Brine <ikegami@​adaelis.com> wrote​:

On Tue, Sep 2, 2014 at 9​:31 PM, Ricardo Signes <perl.p5p@​rjbs.manxome.org>
wrote​:

I am somewhat baffled, as I have never seen "put semicolon at the end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably just a
documentation error, plain and simple, yes?

Correct. Documentation error.

Nothing to do with "..."

perl -e"map { 1, $_; } @​a"
syntax error at -e line 1, near "; }"
Execution of -e aborted due to compilation errors.

I think you could argue this is a bug too, although in the same category as
this​:

perl -le'map { no warnings; $x++ } 1..10'
"no" not allowed in expression at -e line 1, at end of line
BEGIN not safe after errors--compilation aborted at -e line 1.

That is the parser thinks the open { is the beginning of a hash constructor.

This works​:

perl -le'map {; no warnings; $x++ } 1..10'

because the {; tells the parser early enough "this can't be a hash
constructor".

Personally I would love to see a "once and for all" fix to this class of
stupid.

Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"

Copy link
Author

From @cpansprout

On Sat Sep 13 06​:07​:36 2014, jkeenan wrote​:

On Tue Sep 02 18​:31​:46 2014, perl.p5p@​rjbs.manxome.org wrote​:

* ina cpan <perlbug-followup@​perl.org> [2014-08-31T03​:43​:59]

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html
said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

I am somewhat baffled, as I have never seen "put semicolon at the
end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably
just a
documentation error, plain and simple, yes?

In order to move this ticket toward resolution, I have prepared the
patch attached. Please review.

Your patch is good.

--

Father Chrysostomos

Copy link
Author

From @jkeenan

On Sat Sep 13 06​:46​:05 2014, sprout wrote​:

On Sat Sep 13 06​:07​:36 2014, jkeenan wrote​:

On Tue Sep 02 18​:31​:46 2014, perl.p5p@​rjbs.manxome.org wrote​:

* ina cpan <perlbug-followup@​perl.org> [2014-08-31T03​:43​:59]

-----------------------------------------------------------------
The Ellipsis Statement of http​://perldoc.perl.org/perlsyn.html
said,

You can use a ; inside your block to denote that the { ... } is a
block and not a hash reference constructor. Now the ellipsis works​:

1. @​transformed = map {; ... } @​input; # ; disambiguates
2.
3. @​transformed = map { ...; } @​input; # ; disambiguates

I am somewhat baffled, as I have never seen "put semicolon at the
end"
used for
this purpose. It didn't work in v5.12.5. I think this is probably
just a
documentation error, plain and simple, yes?

In order to move this ticket toward resolution, I have prepared the
patch attached. Please review.

Your patch is good.

Thanks for the review. Applied to blead in
commit 12d22d1

Marking ticket resolved.

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

Copy link
Author

@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
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant