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

Return with a bareword compiles under strict #21716

Closed
bbrtj opened this issue Dec 13, 2023 · 5 comments · Fixed by #21729
Closed

Return with a bareword compiles under strict #21716

bbrtj opened this issue Dec 13, 2023 · 5 comments · Fixed by #21729

Comments

@bbrtj
Copy link
Contributor

bbrtj commented Dec 13, 2023

Description

return sum map { ... } @list seems to compile OK under strict without the import of List::Util::sum and returns a filehandle and a mapped list.

Steps to Reproduce
This program shows the behavior:

use warnings;
use strict;

use Data::Dumper;
# use List::Util qw{ sum };

sub xx { return sum map { $_ + 1 } 1 .. 5 }
print Dumper(xx);

The actual error occurs only after you remove return. Removing map causes it to report a warning, but it still runs.

Expected behavior

I expected to get an error about invalid bareword under strict mode, same as without return.

Perl configuration
Behavior is consistent on both perl 5.10.1 and 5.38.2.

@tonycoz
Copy link
Contributor

tonycoz commented Dec 18, 2023

This has to do with the way list ops are parsed. One of the possible productions for a listop in the grammar is:

listop	:	LSTOP indirob listexpr

where LSTOP is the op (OP_RETURN, OP_PRINT etc), indirob is a file handle, and listexpr is the list, this production is used to parse code like:

print HANDLE LIST;

It also parses other code like:

atan2 HANDLE y, x

which parses, but is then rejected in the op's check function (which is Perl_ck_fun, used by many other ops).

I'll look at a fix.

tonycoz added a commit to tonycoz/perl5 that referenced this issue Dec 18, 2023
Since return isn't actually a function, I didn't think the "function"
part of the original message applied.

Fixes Perl#21716
tonycoz added a commit to tonycoz/perl5 that referenced this issue Dec 18, 2023
Since return isn't actually a function, I didn't think the "function"
part of the original message applied.

Fixes Perl#21716
tonycoz added a commit to tonycoz/perl5 that referenced this issue Dec 18, 2023
tonycoz added a commit that referenced this issue Dec 19, 2023
Since return isn't actually a function, I didn't think the "function"
part of the original message applied.

Fixes #21716
tonycoz added a commit that referenced this issue Dec 19, 2023
@rwp0
Copy link
Contributor

rwp0 commented Dec 20, 2023

I expected to get an error about invalid bareword under strict mode, same as without return.

(F) While certain operators allow you to specify a filehandle or an "indirect object" before the argument list, return isn't one of them.

Why not?

Worth mentioning that it's also because return could be implicit (producing different results).

@tonycoz
Copy link
Contributor

tonycoz commented Dec 20, 2023

Why not?

Because it's documented not to do so:

    return EXPR
    return  Returns from a subroutine, "eval", "do FILE", "sort" block or
            regex eval block (but not a "grep", "map", or "do BLOCK" block)
            with the value given in EXPR. Evaluation of EXPR may be in list,
...

The other operators that take an indirect object are output operators like print that treat the object as a file handle, what do you expect return to do with an indirect object?

Worth mentioning that it's also because `return` could be implicit (producing different results).

I'm not sure what you mean here, at first I thought you might mean returning by running off the end of a function, but that's unrelated to the return operator.

@rwp0
Copy link
Contributor

rwp0 commented Dec 20, 2023

Why not?

Because it's documented not to do so:

    return EXPR
    return  Returns from a subroutine, "eval", "do FILE", "sort" block or
            regex eval block (but not a "grep", "map", or "do BLOCK" block)
            with the value given in EXPR. Evaluation of EXPR may be in list,
...

The other operators that take an indirect object are output operators like print that treat the object as a file handle, what do you expect return to do with an indirect object?

Worth mentioning that it's also because `return` could be implicit (producing different results).

I'm not sure what you mean here, at first I thought you might mean returning by running off the end of a function, but that's unrelated to the return operator.

Ah no, I meant if we omit return at the end of a function there won't be issues. This was confusing the OP (poster), apparently. I thought it'd be good to mention that in the message (a fact that sets return apart from the other OPs).

Thank you very much for the commits 👍🏻

@bbrtj
Copy link
Contributor Author

bbrtj commented Dec 21, 2023

Ah no, I meant if we omit return at the end of a function there won't be issues. This was confusing the OP (poster), apparently. I thought it'd be good to mention that in the message (a fact that sets return apart from the other OPs).

I'm not confused, I understand implicit return may not work the same as explicit. I just did not think return should mask errors like that. But I'd rather not to depend on implicit behavior in case of returning.

Thanks for the fix, Tony.

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

Successfully merging a pull request may close this issue.

4 participants