Skip Menu |
Report information
Id: 132744
Status: pending release
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: sisyphus <sisyphus1 [at] optusnet.com.au>
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: low
Type: unknown
Perl Version: (no value)
Fixed In: 5.27.11



To: <perlbug [...] perl.org>
From: <sisyphus1 [...] optusnet.com.au>
Date: Sat, 20 Jan 2018 12:03:40 +1100
Subject: bogus syntax errors with 'use subs'
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
Subject: Re: [perl #132744] bogus syntax errors with 'use subs'
From: Zefram <zefram [...] fysh.org>
Date: Sat, 20 Jan 2018 01:41:59 +0000
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 1.2k
Sisyphus wrote: Show quoted text
>use subs ('FOO'); > >if( FOO < 43) { print "a\n" }
... Show quoted text
>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
Date: Sat, 20 Jan 2018 14:54:46 +1100
Subject: Re: [perl #132744] bogus syntax errors with 'use subs'
To: "Zefram" <zefram [...] fysh.org>, <perl5-porters [...] perl.org>
From: <sisyphus1 [...] optusnet.com.au>
Download (untitled) / with headers
text/plain 1.4k
Show quoted text
-----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
To: perl5-porters [...] perl.org
Subject: Re: [perl #132744] bogus syntax errors with 'use subs'
Date: Sat, 20 Jan 2018 21:33:07 +0100
From: Sawyer X <xsawyerx [...] gmail.com>
Download (untitled) / with headers
text/plain 1.7k
On 01/20/2018 04:54 AM, sisyphus1@optusnet.com.au wrote: Show quoted text
> -----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
RT-Send-CC: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 251b
As of commit dca1ad4686f293a5e83e5ac382f2c55ea6a18f29, 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


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org