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

bogus syntax errors with 'use subs' #16371

Closed
p5pRT opened this issue Jan 20, 2018 · 9 comments
Closed

bogus syntax errors with 'use subs' #16371

p5pRT opened this issue Jan 20, 2018 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 20, 2018

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

Searchable as RT132744$

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2018

From @sisyphus

Hi,

Following are 2 simple scripts that fail to compile.

################################
C​:\_32\pscrpt>type subs.pl

use warnings;
use subs ('FOO');

if( FOO < 43) { print "a\n" }
else { print "b\n" }

sub FOO { return 42 }

C​:\_32\pscrpt>perl subs.pl
Unterminated <> operator at subs.pl line 5.

################################

Pre-declaring 'sub FOO' makes no difference.
The only workarounds I have are to either​:
a) rewrite the condition as 'FOO() < 43';
or
b) rewrite the condition as '43 > FOO'.

################################
C​:\_32\pscrpt>type subs2.pl

use warnings;
use subs ('FOO');

if( FOO <=> 43 ) { print "a\n" }
else { print "b\n" }

sub FOO { return 42 }

C​:\_32\pscrpt>perl subs2.pl
Number found where operator expected at subs2.pl line 5, near "<=> 43"
  (Missing operator before 43?)
syntax error at subs2.pl line 5, near "<=> 43"
Execution of subs2.pl aborted due to compilation errors.
################################

Again, the only workarounds I have are to either append parens to FOO, or to
reverse the order of the operands.

Another failing case (with identical error to the first script) is the
condition 'FOO <= 43'.
I haven't struck such problems with any other comparison operators (in
current perl) - though I might not have tested them all.

Cheers,
Rob

My perl -V is​:

Summary of my perl5 (revision 5 version 27 subversion 7) configuration​:

  Platform​:
  osname=MSWin32
  osvers=6.1.7601
  archname=MSWin32-x64-multi-thread
  uname=''
  config_args='undef'
  hint=recommended
  useposix=true
  d_sigaction=undef
  useithreads=define
  usemultiplicity=define
  use64bitint=define
  use64bitall=undef
  uselongdouble=undef
  usemymalloc=n
  default_inc_excludes_dot=define
  bincompat5005=undef
  Compiler​:
  cc='gcc'
  ccflags
' -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT
-DPERL_IMPLICIT_SYS -DUSE_PERLIO -D__USE_MINGW_ANSI_STDIO -fwrapv -fno-strict-aliasing
-mms-bitfields'
  optimize='-s -O2'
  cppflags='-DWIN32'
  ccversion=''
  gccversion='7.2.0'
  gccosandvers=''
  intsize=4
  longsize=4
  ptrsize=8
  doublesize=8
  byteorder=12345678
  doublekind=3
  d_longlong=define
  longlongsize=8
  d_longdbl=define
  longdblsize=16
  longdblkind=3
  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​:\_64\blead-5.27.7\lib\CORE" -L"C​:\_64\gcc-mingw-720\mingw64\lib"'
  libpth=C​:\_64\gcc-mingw-720\mingw64\lib
C​:\_64\gcc-mingw-720\mingw64\x86_64-w64-mingw32\lib
C​:\_64\msys_720\1.0\local\lib
C​:\_64\gcc-mingw-720\mingw64\lib\gcc\x86_64-w64-mingw32\7.2.0
  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=libperl527.a
  gnulibc_version=''
  Dynamic Linking​:
  dlsrc=dl_win32.xs
  dlext=dll
  d_dlsymun=undef
  ccdlflags=' '
  cccdlflags=' '
  lddlflags='-mdll -s -L"C​:\_64\blead-5.27.7\lib\CORE" -L"C​:\_64\gcc-mingw-720\mingw64\lib"'

Characteristics of this binary (from libperl)​:
  Compile-time options​:
  HAS_TIMES
  HAVE_INTERP_INTERN
  MULTIPLICITY
  PERLIO_LAYERS
  PERL_COPY_ON_WRITE
  PERL_DONT_CREATE_GVSV
  PERL_IMPLICIT_CONTEXT
  PERL_IMPLICIT_SYS
  PERL_MALLOC_WRAP
  PERL_OP_PARENT
  PERL_PRESERVE_IVUV
  USE_64_BIT_INT
  USE_ITHREADS
  USE_LARGE_FILES
  USE_LOCALE
  USE_LOCALE_COLLATE
  USE_LOCALE_CTYPE
  USE_LOCALE_NUMERIC
  USE_LOCALE_TIME
  USE_PERLIO
  USE_PERL_ATOF
  Built under MSWin32
  Compiled at Dec 21 2017 15​:18​:15
  @​INC​:
  C​:/_64/blead-5.27.7/site/lib
  C​:/_64/blead-5.27.7/lib

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2018

From zefram@fysh.org

Sisyphus wrote​:

use subs ('FOO');

if( FOO < 43) { print "a\n" }
...
Unterminated <> operator at subs.pl line 5.

Both of your failures have the same cause​: the "<" is interpreted
as the start of an argument expression, rather than as an operator.
This is not specific to "use subs", and actually happens with any kind
of predeclaration, unless you give an empty prototype​:

$ perl -lwe 'sub FOO; if (FOO < 43) { print "a"; } sub FOO { return 42; }'
Unterminated <> operator at -e line 1.
$ perl -lwe 'sub FOO { return 42; } if (FOO < 43) { print "a"; }'
Unterminated <> operator at -e line 1.

The same problem applies to other characters that can be either the
start of a term or an infix operator​:

$ perl -lwe 'sub FOO { return 42; } print FOO + 1; print FOO() + 1'
42
43

This isn't a bug, but an intentional grammatical feature. Using explicit
parens to delimit the empty argument list is one solution, as you've
found. The other solution is to give the sub an empty prototype, which
alters its grammatical role such that the ambiguous characters will be
interpreted as infix operators​:

$ perl -lwe 'sub FOO () { return 42; } if (FOO < 43) { print "a"; } print FOO + 1'
a
43
$ perl -lwe 'sub FOO (); if (FOO < 43) { print "a"; } print FOO + 1; sub FOO () { return 42; }'
a
43

-zefram

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2018

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

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2018

From @sisyphus

-----Original Message-----
From​: Zefram
Sent​: Saturday, January 20, 2018 12​:41 PM
To​: perl5-porters@​perl.org
Subject​: Re​: [perl #132744] bogus syntax errors with 'use subs'

Sisyphus wrote​:

use subs ('FOO');

if( FOO < 43) { print "a\n" }
...
Unterminated <> operator at subs.pl line 5.

This isn't a bug, but an intentional grammatical feature. Using explicit
parens to delimit the empty argument list is one solution, as you've
found. The other solution is to give the sub an empty prototype, which
alters its grammatical role such that the ambiguous characters will be
interpreted as infix operators​:

$ perl -lwe 'sub FOO () { return 42; } if (FOO < 43) { print "a"; } print
FOO + 1'
a
43

I hadn't thought of that solution - and it's a very useful one because,
unlike my workarounds, it's something that I can use to solve the actual
issue I have.

However, I think the subs documentation should at least acknowledge this
issue, and also mention that solution. (I don't think it needs to be a
detailed coverage.)

Currently the documentation simply states that use subs " will predeclare
all the subroutine whose names are in the list, allowing you to use them
without parentheses even before they're declared".
And my demos (which meet the requirements of that documentation) clearly
show it's not always as simple as that.

(I just noticed a small typo in that section of the docs that I quoted -
"subroutine" should be plural, not singular.)

Cheers,
Rob

@p5pRT
Copy link
Author

p5pRT commented Jan 20, 2018

From @xsawyerx

On 01/20/2018 04​:54 AM, sisyphus1@​optusnet.com.au wrote​:

-----Original Message----- From​: Zefram
Sent​: Saturday, January 20, 2018 12​:41 PM
To​: perl5-porters@​perl.org
Subject​: Re​: [perl #132744] bogus syntax errors with 'use subs'

Sisyphus wrote​:

use subs ('FOO');

if( FOO < 43) { print "a\n" }
...
Unterminated <> operator at subs.pl line 5.

This isn't a bug, but an intentional grammatical feature.  Using
explicit parens to delimit the empty argument list is one solution,
as you've found.  The other solution is to give the sub an empty
prototype, which alters its grammatical role such that the ambiguous
characters will be
interpreted as infix operators​:

$ perl -lwe 'sub FOO () { return 42; } if (FOO < 43) { print "a"; }
print FOO + 1'
a
43

I hadn't thought of that solution - and it's a very useful one
because, unlike my workarounds, it's something that I can use to solve
the actual issue I have.

However, I think the subs documentation should at least acknowledge
this issue, and also mention that solution. (I don't think it needs to
be a detailed coverage.)

Currently the documentation simply states that use subs " will
predeclare all the subroutine whose names are in the list, allowing
you to use them without parentheses even before they're declared".
And my demos (which meet the requirements of that documentation)
clearly show it's not always as simple as that.

(I just noticed a small typo in that section of the docs that I quoted
- "subroutine" should be plural, not singular.)

Relevant to this is the following Perl​::Critic policy​:

https://metacpan.org/pod/Perl::Critic::Policy::ValuesAndExpressions::ConstantBeforeLt

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2018

From @arc

As of commit dca1ad4, the documentation for subs.pm clarifies that it allows the declared subroutines to be used as list operators.

This change will be in 5.27.11 (due to be released today) and 5.28.

--
Aaron Crane

@p5pRT
Copy link
Author

p5pRT commented Apr 20, 2018

@arc - Status changed from 'open' to 'pending release'

@p5pRT
Copy link
Author

p5pRT commented Jun 23, 2018

From @khwilliamson

Thank you for filing this report. You have helped make Perl better.

With the release yesterday of Perl 5.28.0, this and 185 other issues have been
resolved.

Perl 5.28.0 may be downloaded via​:
https://metacpan.org/release/XSAWYERX/perl-5.28.0

If you find that the problem persists, feel free to reopen this ticket.

@p5pRT
Copy link
Author

p5pRT commented Jun 23, 2018

@khwilliamson - Status changed from 'pending release' 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