Closed p5pRT closed 8 years ago
$ perl -wle 'my (my $a) = 3; print $a' 3
The optree deparses as if there is only one my:
$ perl -MO=Deparse -e 'my (my $a) = 3;' my($a) = 3; -e syntax OK
Shouldn't chained my be a syntax error? (and yes\, you can do silly things in 5.10nearly with state and my)
Nicholas Clark
On Sat Sep 08 05:33:17 2007\, nicholas wrote:
$ perl -wle 'my (my $a) = 3; print $a' 3
The optree deparses as if there is only one my:
$ perl -MO=Deparse -e 'my (my $a) = 3;' my($a) = 3; -e syntax OK
Shouldn't chained my be a syntax error?
Iâd call that a feature. :-)
Isnât that what allows my(undef) to work?
The RT System itself - Status changed from 'new' to 'open'
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this. What does it even mean?
* l.mai@web.de \perlbug\-followup@​perl\.org [2015-07-09 22:30]:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this.
Why? Did you just write that accidentally and spent 3 days looking for the problem?
What does it even mean?
It means you can write things like these:
my ($foo\, undef\, $bar) = split ' '; ($foo\, my $bar\, $baz) = get_record_columns();
Because these are legal\, your examples happen to also be legal.
Your first example declares a lexical variable and the second a state variable\, in case you are wondering. The rule is that the inner-most declarator wins. Itâs very simple and predictable\, and easy to read correctly.
To still allow examples I gave\, but disallow the ones you showed\, perl would have to go out of its way to check for such cases so it can croak. Do you think this would be effort and code complexity well spent?
The RT System itself - Status changed from 'new' to 'open'
On Sat\, Jul 11\, 2015 at 02:41:30AM +0200\, Aristotle Pagaltzis wrote:
* l.mai@web.de \perlbug\-followup@​perl\.org [2015-07-09 22:30]:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this.
Why? Did you just write that accidentally and spent 3 days looking for the problem?
What does it even mean?
It means you can write things like these:
my \($foo\, undef\, $bar\) = split ' '; \($foo\, my $bar\, $baz\) = get\_record\_columns\(\);
Because these are legal\, your examples happen to also be legal.
Neither example is a case of stacked declarations. The fact that the one implies the other seems like an artifact of the implementation\, not a necessity.
Your first example declares a lexical variable and the second a state variable\, in case you are wondering. The rule is that the inner-most declarator wins. Itâs very simple and predictable\, and easy to read correctly.
To still allow examples I gave\, but disallow the ones you showed\, perl would have to go out of its way to check for such cases so it can croak. Do you think this would be effort and code complexity well spent?
That's a completely different question. I don't think having stacked declaration causes problems that often -- a check for this belongs\, IMO\, in Perl::Critic.
I do remember having written 'local our $var' (or 'our local $var') in the past\, but I don't recall whether it was really the best option in that case\, or whether it was just a proof of concept.
Abigail
On Fri Jul 10 17:42:02 2015\, aristotle wrote:
* l.mai@web.de \perlbug\-followup@​perl\.org [2015-07-09 22:30]:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this.
Why?
Because it looks like semantic nonsense to me.
Did you just write that accidentally and spent 3 days looking for the problem?
No\, I was actually looking for B::Deparse bugs\, but why does that matter?
What does it even mean?
It means you can write things like these:
my \($foo\, undef\, $bar\) = split ' '; \($foo\, my $bar\, $baz\) = get\_record\_columns\(\);
Because these are legal\, your examples happen to also be legal.
That doesn't follow. Like\, at all.
1) Your example tells me nothing about what "my (our $x)" should do. What are the semantics of declaring a declaration\, and why should that be part of the language?
2) 'my ($foo = 42);' could have a sensible interpretation but it's illegal: Can't declare scalar assignment in "my" at -e line 1\, near ");"
In fact\, almost all syntactic constructs are not allowed in a 'my' list and 'undef' is a special case. Why make my/our/state a special case\, too?
I don't see how '($foo\, my $bar\, $baz)' is related; it doesn't use 'my (...)'.
Your first example declares a lexical variable and the second a state variable\, in case you are wondering. The rule is that the inner-most declarator wins. Itâs very simple and predictable\, and easy to read correctly.
You just made that "rule" up. It's certainly not documented anywhere and I doubt it was intended to work this way. Maybe it's a consequence of how the parser happens to set flags but do you want to guarantee to preserve this behavior in future versions?
To still allow examples I gave\, but disallow the ones you showed\, perl would have to go out of its way to check for such cases so it can croak. Do you think this would be effort and code complexity well spent?
Perl already checks for and disallows any expression but undef. This argument sounds too much like "but fixing this bug would be hard" for my liking.
On Fri Jul 10 23:54:31 2015\, abigail@abigail.be wrote:
I do remember having written 'local our $var' (or 'our local $var') in the past\, but I don't recall whether it was really the best option in that case\, or whether it was just a proof of concept.
I've written 'local our $var' too\, and it makes sense to me because 'local' is not a declarator.
I'm surprised to see that 'our(local $var)' is allowed and does the same thing. It feels analogous to 'our($var = undef)' to me (which is illegal).
On Fri Jul 10 17:42:02 2015\, aristotle wrote:
To still allow examples I gave\, but disallow the ones you showed\, perl would have to go out of its way to check for such cases so it can croak. Do you think this would be effort and code complexity well spent?
"What\, like it's hard?" - Elle Woods
See also [perl #121058].
-zefram
* Abigail \abigail@​abigail\.be [2015-07-11 08:55]:
On Sat\, Jul 11\, 2015 at 02:41:30AM +0200\, Aristotle Pagaltzis wrote:
It means you can write things like these:
my \($foo\, undef\, $bar\) = split ' '; \($foo\, my $bar\, $baz\) = get\_record\_columns\(\);
Because these are legal\, your examples happen to also be legal.
Neither example is a case of stacked declarations. The fact that the one implies the other seems like an artifact of the implementation\, not a necessity.
Thatâs why I said âhappens to beâ. :-)
I don't think having stacked declaration causes problems that often
The only time I wrote stacked declarators is when I realised they must be legal and tried it to confirm my hypothesis. Then I wrote a short funny post on my blog about them and forgot them again. This was not too long ago\, ~20 years into doing Perl and never encountering them in any code\, mine or othersâ.
Itâs possible that it is a good idea to ban them\, although it seems dubious to me based on the evidence so far. Just because a construct is nonsense doesnât mean it must be illegal\, so long as users never stub their toes on it. Hence my question about whether Lukas did.
I do remember having written 'local our $var' (or 'our local $var') in the past\, but I don't recall whether it was really the best option in that case\, or whether it was just a proof of concept.
And of course\, that one has an obvious and sensical meaningâŠ
Regards\, -- Aristotle Pagaltzis // \<http://plasmasturm.org/>
* l.mai@web.de via RT \perlbug\-followup@​perl\.org [2015-07-11 10:35]:
On Fri Jul 10 17:42:02 2015\, aristotle wrote:
Why?
Because it looks like semantic nonsense to me.
But nothing follows from that. Any generic system of rules allows you to construct consistent but nonsensical expressions. Trying to legislate that only useful expressions are permitted is a foolâs errand.
No\, I was actually looking for B::Deparse bugs\, but why does that matter?
Because that might be an actual reason to do or not do something.
What does it even mean?
It means you can write things like these:
my \($foo\, undef\, $bar\) = split ' '; \($foo\, my $bar\, $baz\) = get\_record\_columns\(\);
Because these are legal\, your examples happen to also be legal.
That doesn't follow. Like\, at all.
1) Your example tells me nothing about what "my (our $x)" should do. What are the semantics of declaring a declaration\, and why should that be part of the language?
2) 'my ($foo = 42);' could have a sensible interpretation but it's illegal: Can't declare scalar assignment in "my" at -e line 1\, near ");"
In fact\, almost all syntactic constructs are not allowed in a 'my' list and 'undef' is a special case. Why make my/our/state a special case\, too?
I donât believe declarators are special-cased here the way you seem convinced they are. You cannot write `$foo = 42` anywhere a variable name is expected\, so itâs no stretch that it wouldnât be allowed inside a declaratorâs variable name list either. You *can* throw declarators into any expression anywhere a variable is expected\, to declare and use it en passant. It seems to me that this is how stacked declarators happen to end up legal â i.e. how what you say doesnât follow\, like\, at all\, actually does follow.
I don't see how '($foo\, my $bar\, $baz)' is related; it doesn't use 'my (...)'.
OK\, here you go:
($foo\, my ($bar\, $baz)\, $quux) = get_record_columns();
Your first example declares a lexical variable and the second a state variable\, in case you are wondering. The rule is that the inner-most declarator wins. Itâs very simple and predictable\, and easy to read correctly.
You just made that "rule" up.
In my own memory of the incident\, I tested a few years ago whether that is how it works\, and I found that it was. Is my recollection faulty?
It's certainly not documented anywhere and I doubt it was intended to work this way. Maybe it's a consequence of how the parser happens to set flags but do you want to guarantee to preserve this behavior in future versions?
I donât know. Maybe I am mistaken about how obviously it follows from other rules. It would hardly be the first implementation-defined aspect of Perl 5 in any case. Is the behaviour that fragile and likely to break? This says maybe so:
* Zefram \zefram@​fysh\.org [2015-07-11 13:30]:
See also [perl #121058].
If it is really so precarious\, it may be worth banning after all. Very little code would (probably) suffer anyhow.
* l.mai@web.de via RT \perlbug\-followup@​perl\.org [2015-07-11 10:35]:
To still allow examples I gave\, but disallow the ones you showed\, perl would have to go out of its way to check for such cases so it can croak. Do you think this would be effort and code complexity well spent?
Perl already checks for and disallows any expression but undef. This argument sounds too much like "but fixing this bug would be hard" for my liking.
I believe you are far overestimating the special-casing for undef here\, as outlined above.
This is not about how hard it would be to fix\, itâs about whether it makes sense to make even a trivial effort to fix it\, and then have to keep that trivial effort working forever after. Just because it looks stupid that you can do something doesnât mean it has to be prohibited.
* l.mai@web.de via RT \perlbug\-followup@​perl\.org [2015-07-11 10:40]:
I'm surprised to see that 'our(local $var)' is allowed and does the same thing. It feels analogous to 'our($var = undef)' to me (which is illegal).
That surprised me too.
Regards\, -- Aristotle Pagaltzis // \<http://plasmasturm.org/>
On Sat Jul 11 06:49:45 2015\, aristotle wrote:
OK\, here you go:
($foo\, my ($bar\, $baz)\, $quux) = get_record_columns();
You still donât have stacked declarators there. I was about to say that I have actually used stacked declarators in my code\, but I looked and the code actually has:
(my $types\, local our ($tokens\,$prepped\,$alt_types)) = _prep_val(@_);
Though I *think* I may have used stacked declarators somewhere. I donât think it would be good to remove them\, because of the risk of breaking code.
--
Father Chrysostomos
On Sat Jul 11 06:57:43 2015\, sprout wrote:
On Sat Jul 11 06:49:45 2015\, aristotle wrote:
OK\, here you go:
($foo\, my ($bar\, $baz)\, $quux) = get_record_columns();
You still donât have stacked declarators there. I was about to say that I have actually used stacked declarators in my code\, but I looked and the code actually has:
(my $types\, local our ($tokens\,$prepped\,$alt_types)) = _prep_val(@_);
Though I *think* I may have used stacked declarators somewhere. I donât think it would be good to remove them\, because of the risk of breaking code.
That code is already broken. See [perl #121058] (thanks\, Zefram):
% perl -MO=Deparse -e 'use feature "state"; state ($x\, my $y\, $z)' use feature 'state'; state $x\, my $y\, our $z; -e syntax OK
Here we get a bogus 'our' that isn't in the source.
% perl -MO=Deparse -e 'use strict; use feature "state"; state ($x\, my $y\, $z)' Global symbol "$z" requires explicit package name (did you forget to declare "my $z"?) at -e line 1. -e had compilation errors. use strict; use feature 'state'; $x\, my $y\, ${'z'};
... except it's not a real declaration because it trips strict 'vars'\, despite being inside a 'state'.
In my opinion we should either make this work consistently (e.g. by deciding that the inner declarator always wins and fixing the parser) or by disallowing the whole construct (my proof-of-concept patch produces 'Can't redeclare "my" in "state" at -e line 1\, near "\, "' for this case).
On Sat\, Jul 11\, 2015 at 2:53 AM\, Abigail \abigail@​abigail\.be wrote:
I do remember having written 'local our $var' (or 'our local $var') in the past\, but I don't recall whether it was really the best option in that case\, or whether it was just a proof of concept.
"local" is not a declerator. "local our" is quite common.
sub foo { our $alias; local our *alias = \shift; ... }
On Sun\, Jul 12\, 2015 at 1:37 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
On Sat\, Jul 11\, 2015 at 2:53 AM\, Abigail \abigail@​abigail\.be wrote:
I do remember having written 'local our $var' (or 'our local $var') in the past\, but I don't recall whether it was really the best option in that case\, or whether it was just a proof of concept.
"local" is not a declerator.
Ignore the following. The second "our" shouldn't be there.
"local our" is quite common.
sub foo { our $alias; local our *alias = \shift; ... }
On Thu Jul 09 13:25:39 2015\, mauke- wrote:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this. What does it even mean?
Fixed in blead by commit f3106bc89eb4bbffee5ca7cb67bd63d2f3ce87bf. This makes nested declarations an error.
On Thu Jul 09 13:25:39 2015\, mauke- wrote:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this. What does it even mean?
Fixed in blead by commit f3106bc89eb4bbffee5ca7cb67bd63d2f3ce87bf. This makes nested declarations an error.
On Tue\, Aug 25\, 2015 at 4:15 AM\, l.mai@web.de via RT \< perlbug-comment@perl.org> wrote:
On Thu Jul 09 13:25:39 2015\, mauke- wrote:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this. What does it even mean?
Fixed in blead by commit f3106bc89eb4bbffee5ca7cb67bd63d2f3ce87bf. This makes nested declarations an error.
Is "local our" still allowed?
On Tue\, Aug 25\, 2015 at 9:43 AM\, Eric Brine \ikegami@​adaelis\.com wrote:
On Tue\, Aug 25\, 2015 at 4:15 AM\, l.mai@web.de via RT \< perlbug-comment@perl.org> wrote:
On Thu Jul 09 13:25:39 2015\, mauke- wrote:
% perl -wE 'our (my $x)' % perl -wE 'my (state $x)' %
I don't think perl should allow this. What does it even mean?
Fixed in blead by commit f3106bc89eb4bbffee5ca7cb67bd63d2f3ce87bf. This makes nested declarations an error.
Is "local our" still allowed?
Looked at the patch. It doesn't affect local at all.
@mauke - Status changed from 'open' to 'pending release'
Thank you for submitting this report. You have helped make Perl better.
With the release of Perl 5.24.0 on May 9\, 2016\, this and 149 other issues have been resolved.
Perl 5.24.0 may be downloaded via https://metacpan.org/release/RJBS/perl-5.24.0
@khwilliamson - Status changed from 'pending release' to 'resolved'
This was "fixed"\, and there is now a test for it in t/lib/croak/toke
dcollins@nightshade64:\~/toolchain/perl$ perl5.23.1 -wle 'my (my $a) = 3; print $a' 3 dcollins@nightshade64:\~/toolchain/perl$ perl5.23.2 -wle 'my (my $a) = 3; print $a' Can't redeclare "my" in "my" at -e line 1\, at end of line Execution of -e aborted due to compilation errors.
-- Respectfully\, Dan Collins
Migrated from rt.perl.org#125587 (status was 'resolved')
Searchable as RT125587$