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

Sort autoquotes a following bareword under strict #16548

Open
p5pRT opened this issue May 5, 2018 · 9 comments
Open

Sort autoquotes a following bareword under strict #16548

p5pRT opened this issue May 5, 2018 · 9 comments

Comments

@p5pRT
Copy link

p5pRT commented May 5, 2018

Migrated from rt.perl.org#133178 (status was 'open')

Searchable as RT133178$

@p5pRT
Copy link
Author

p5pRT commented May 5, 2018

From @Grinnz

If the first token passed to a sort call is a bareword, and it's not a sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

-Dan

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

From @tonycoz

On Sat, 05 May 2018 09​:19​:25 -0700, grinnz@​gmail.com wrote​:

If the first token passed to a sort call is a bareword, and it's not a sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

I can't see us changing this long standing, presumably by design behaviour.

The attached more clearly documents the first case for SUBNAME as being a bareword, and that use strict doesn't prevent it.

Tony

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

From @tonycoz

0001-perl-133178-more-clearly-document-SUBNAME-as-barewor.patch
From 20415b968e8860b17c6aca264ea282bba187e852 Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Thu, 31 May 2018 15:23:11 +1000
Subject: (perl #133178) more clearly document SUBNAME as bareword for sort()

---
 pod/perlfunc.pod | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index fa08d4c3e9..0a9b7917ac 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -7352,14 +7352,16 @@ undefined.
 
 If SUBNAME or BLOCK is omitted, L<C<sort>|/sort SUBNAME LIST>s in
 standard string comparison
-order.  If SUBNAME is specified, it gives the name of a subroutine
+order.  If SUBNAME is specified as a bareword, it gives the name of a
+subroutine
 that returns an integer less than, equal to, or greater than C<0>,
 depending on how the elements of the list are to be ordered.  (The
 C<< <=> >> and C<cmp> operators are extremely useful in such routines.)
 SUBNAME may be a scalar variable name (unsubscripted), in which case
 the value provides the name of (or a reference to) the actual
 subroutine to use.  In place of a SUBNAME, you can provide a BLOCK as
-an anonymous, in-line sort subroutine.
+an anonymous, in-line sort subroutine.  A bareword SUBNAME is permitted
+even under C<use strict;>.
 
 If the subroutine's prototype is C<($$)>, the elements to be compared are
 passed by reference in L<C<@_>|perlvar/@_>, as for a normal subroutine.
-- 
2.11.0

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

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

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

From @Grinnz

On Wed, 30 May 2018 22​:25​:17 -0700, tonyc wrote​:

On Sat, 05 May 2018 09​:19​:25 -0700, grinnz@​gmail.com wrote​:

If the first token passed to a sort call is a bareword, and it's not
a sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

I can't see us changing this long standing, presumably by design
behaviour.

The attached more clearly documents the first case for SUBNAME as
being a bareword, and that use strict doesn't prevent it.

Tony

The more confusing aspect of the behavior, which doesn't seem as intentional, is that it quotes the first token even when it doesn't end up being interpreted as the SUBNAME.

-Dan

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

From Eirik-Berg.Hanssen@allverden.no

On Thu, May 31, 2018 at 10​:31 PM, Eirik Berg Hanssen <
Eirik-Berg.Hanssen@​allverden.no> wrote​:

I can't imagine this is by design behaviour, but if you want to document
it, the current behaviour is that a bareword immediately following "sort"
will be used as a string (not a SUBNAME) when no subroutine by that name
exists.

... except it will fail to compile if followed by a comma, and if
followed by a term, it will nonetheless use the bareword as a subname (and
not indirect object syntax, as it might otherwise be), and fail at runtime,
unless the routine has been created by then ...

Wouldn't it make more sense to do the latter in general, that is, permit
the bareword, but treat as a subname to be looked up at runtime (and never
a string)? Or at least, under strict?

  Hang on, isn't that behaviour consistent with what your patch documents?

  I guess it would make more sense, huh? :)

Eirik

@p5pRT
Copy link
Author

p5pRT commented May 31, 2018

From Eirik-Berg.Hanssen@allverden.no

On Thu, May 31, 2018 at 7​:25 AM, Tony Cook via RT <perlbug-followup@​perl.org

wrote​:

On Sat, 05 May 2018 09​:19​:25 -0700, grinnz@​gmail.com wrote​:

If the first token passed to a sort call is a bareword, and it's not a
sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line 1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

I can't see us changing this long standing, presumably by design behaviour.

The attached more clearly documents the first case for SUBNAME as being a
bareword, and that use strict doesn't prevent it.

  That doesn't document what actually happens in his first case, does it?

  If SUBNAME or BLOCK is omitted, L<C<sort>|/sort SUBNAME LIST>s in

standard string comparison
-order. If SUBNAME is specified, it gives the name of a subroutine
+order. If SUBNAME is specified as a bareword, it gives the name of a
+subroutine
that returns an integer less than, equal to, or greater than C<0>,
depending on how the elements of the list are to be ordered.

  Because in his first case, the bareword does not give "the name of a
subroutine". It gives a string.

  I can't imagine this is by design behaviour, but if you want to document
it, the current behaviour is that a bareword immediately following "sort"
will be used as a string (not a SUBNAME) when no subroutine by that name
exists.

  ... except it will fail to compile if followed by a comma, and if
followed by a term, it will nonetheless use the bareword as a subname (and
not indirect object syntax, as it might otherwise be), and fail at runtime,
unless the routine has been created by then ...

  Wouldn't it make more sense to do the latter in general, that is, permit
the bareword, but treat as a subname to be looked up at runtime (and never
a string)? Or at least, under strict?

Eirik

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2018

From @cpansprout

On Wed, 30 May 2018 22​:25​:17 -0700, tonyc wrote​:

On Sat, 05 May 2018 09​:19​:25 -0700, grinnz@​gmail.com wrote​:

If the first token passed to a sort call is a bareword, and it's not
a sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

I can't see us changing this long standing, presumably by design
behaviour.

I don’t think it’s by design. It’s an accident of the implementation, resulting from code written with Perl 4 assumptions in mind. I.e., we are dealing with some very OLD code, in the lexer. I tried taking a stab at it before, but failed.

The attached more clearly documents the first case for SUBNAME as
being a bareword, and that use strict doesn't prevent it.

Your patch does not mention the behaviour reported here, that a bareword gets quoted even if it is not interpreted as a subroutine.

The reason this is hard to fix is that the lexer doesn’t know at the time that it emits the bareword whether it will be interpreted as the sort subroutine. The parser handles the latter, but by then it’s too late. (Maybe there is some way to reverse the lexer when that particular path in the parser is taken.)

--

Father Chrysostomos

@p5pRT
Copy link
Author

p5pRT commented Jun 1, 2018

From @cpansprout

On Wed, 30 May 2018 22​:25​:17 -0700, tonyc wrote​:

On Sat, 05 May 2018 09​:19​:25 -0700, grinnz@​gmail.com wrote​:

If the first token passed to a sort call is a bareword, and it's not
a sort
routine, sort appears to autoquote it, ignoring strict 'subs'.

perl -E'use strict; say sort bareword'
bareword

perl -E'use strict; say sort bareword . "bareword"'
barewordbareword

Anything between sort and the bareword makes strict 'subs' work.

perl -E'use strict; say sort +bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort {$a cmp $b} bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

perl -E'use strict; say sort bareword . bareword'
Bareword "bareword" not allowed while "strict subs" in use at -e line
1.
Execution of -e aborted due to compilation errors.

This behavior should be documented, if not fixed.

I can't see us changing this long standing, presumably by design
behaviour.

The attached more clearly documents the first case for SUBNAME as
being a bareword, and that use strict doesn't prevent it.

Tony

The patch itself is good, BTW. I have nothing against applying it. It clarifies what happens in those cases where the lexer and the parser are actually coöperating and not talking past each other.

--

Father Chrysostomos

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

2 participants