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

stacked declarators (my/our/state) shouldn't be legal #14799

Closed
p5pRT opened this issue Jul 9, 2015 · 26 comments
Closed

stacked declarators (my/our/state) shouldn't be legal #14799

p5pRT opened this issue Jul 9, 2015 · 26 comments

Comments

@p5pRT
Copy link
Collaborator

@p5pRT p5pRT commented Jul 9, 2015

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

Searchable as RT125587$

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Sep 8, 2007

From @nwc10

Created by @nwc10

$ 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

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl v5.8.8:

Configured by mstevens at Wed Jul 11 21:30:26 BST 2007.

Summary of my perl5 (revision 5 version 8 subversion 8) configuration:
  Platform:
    osname=freebsd, osvers=6.2-release-p4, archname=i386-freebsd-64int
    uname='freebsd saigo.etla.org 6.2-release-p4 freebsd 6.2-release-p4 #2: sun apr 29 08:28:44 bst 2007 root@saigo.etla.org:usrobjusrsrcsyssaigo2 i386 '
    config_args='-sde -Dprefix=/usr/local -Darchlib=/usr/local/lib/perl5/5.8.8/mach -Dprivlib=/usr/local/lib/perl5/5.8.8 -Dman3dir=/usr/local/lib/perl5/5.8.8/perl/man/man3 -Dman1dir=/usr/local/man/man1 -Dsitearch=/usr/local/lib/perl5/site_perl/5.8.8/mach -Dsitelib=/usr/local/lib/perl5/site_perl/5.8.8 -Dscriptdir=/usr/local/bin -Dsiteman3dir=/usr/local/lib/perl5/5.8.8/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Ui_malloc -Ui_iconv -Uinstallusrbinperl -Dcc=cc -Duseshrplib -Dccflags=-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -Doptimize=-O2 -fno-strict-aliasing -pipe -march=pentium4 -Ud_dosuid -Ui_gdbm -Dusethreads=n -Dusemymalloc=y -Duse64bitint'
    hint=recommended, useposix=true, d_sigaction=define
    usethreads=undef use5005threads=undef useithreads=undef usemultiplicity=undef
    useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
    use64bitint=define use64bitall=undef uselongdouble=undef
    usemymalloc=y, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include',
    optimize='-O2 -fno-strict-aliasing -pipe -march=pentium4',
    cppflags='-DAPPLLIB_EXP="/usr/local/lib/perl5/5.8.8/BSDPAN" -DHAS_FPSETMASK -DHAS_FLOATINGPOINT_H -fno-strict-aliasing -pipe -Wdeclaration-after-statement -I/usr/local/include'
    ccversion='', gccversion='3.4.6 [FreeBSD] 20060305', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -Wl,-E -L/usr/local/lib'
    libpth=/usr/lib /usr/local/lib
    libs=-lm -lcrypt -lutil
    perllibs=-lm -lcrypt -lutil
    libc=, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version=''
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='  -Wl,-R/usr/local/lib/perl5/5.8.8/mach/CORE'
    cccdlflags='-DPIC -fPIC', lddlflags='-shared  -L/usr/local/lib'

Locally applied patches:
    defined-or


@INC for perl v5.8.8:
    /usr/local/lib/perl5/5.8.8/BSDPAN
    /usr/local/lib/perl5/site_perl/5.8.8/mach
    /usr/local/lib/perl5/site_perl/5.8.8
    /usr/local/lib/perl5/site_perl
    /usr/local/lib/perl5/5.8.8/mach
    /usr/local/lib/perl5/5.8.8
    .


Environment for perl v5.8.8:
    HOME=/home/nick
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/nick/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/usr/X11R6/bin:/home/nick/bin:/usr/local/sbin:/sbin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/usr/local/bin/bash

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 12, 2010

From @cpansprout

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?

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Dec 12, 2010

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 9, 2015

From @mauke

Created by @mauke

% perl -wE 'our (my $x)'
% perl -wE 'my (state $x)'
%

I don't think perl should allow this. What does it even mean?

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.22.0:

Configured by mauke at Sat Jul  4 14:56:57 CEST 2015.

Summary of my perl5 (revision 5 version 22 subversion 0) configuration:
   
  Platform:
    osname=linux, osvers=4.0.1-1-arch, archname=i686-linux
    uname='linux simplicio 4.0.1-1-arch #1 smp preempt wed apr 29 12:15:20 cest 2015 i686 gnulinux '
    config_args=''
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=undef, usemultiplicity=undef
    use64bitint=undef, use64bitall=undef, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-O2',
    cppflags='-fwrapv -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='5.1.0', gccosandvers=''
    intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234, doublekind=3
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12, longdblkind=3
    ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=4, prototype=define
  Linker and Libraries:
    ld='cc', ldflags ='-fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/i686-pc-linux-gnu/5.1.0/include-fixed /usr/lib /lib
    libs=-lpthread -lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lc -lgdbm_compat
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.21.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.21'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector'



@INC for perl 5.22.0:
    /home/mauke/usr/lib/perl5/site_perl/5.22.0/i686-linux
    /home/mauke/usr/lib/perl5/site_perl/5.22.0
    /home/mauke/usr/lib/perl5/5.22.0/i686-linux
    /home/mauke/usr/lib/perl5/5.22.0
    .


Environment for perl 5.22.0:
    HOME=/home/mauke
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_COLLATE=POSIX
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/mauke/perl5/perlbrew/bin:/home/mauke/bin:/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
    PERLBREW_BASHRC_VERSION=0.69
    PERLBREW_HOME=/home/mauke/.perlbrew
    PERLBREW_ROOT=/home/mauke/perl5/perlbrew
    PERL_BADLANG (unset)
    PERL_UNICODE=SAL
    SHELL=/bin/bash

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @ap

* 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?

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @Abigail

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @mauke

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.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @mauke

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).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @mauke

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @mauke

0001-PoC-disallow-stacked-declarators-125587.patch
From 4df2dafa76162572f99bf01c7222ea9601025375 Mon Sep 17 00:00:00 2001
From: Lukas Mai <l.mai@web.de>
Date: Sat, 11 Jul 2015 10:38:53 +0200
Subject: [PATCH] PoC: disallow stacked declarators [#125587]

---
 toke.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/toke.c b/toke.c
index 763baa5..560c2fa 100644
--- a/toke.c
+++ b/toke.c
@@ -7543,6 +7543,15 @@ Perl_yylex(pTHX)
 	case KEY_our:
 	case KEY_my:
 	case KEY_state:
+	    if (PL_in_my) {
+	        yyerror(Perl_form(aTHX_
+	                    "Can't redeclare \"%s\" in \"%s\"",
+			       tmp      == KEY_my    ? "my"    :
+			       tmp      == KEY_state ? "state" : "our",
+			       PL_in_my == KEY_my    ? "my"    :
+			       PL_in_my == KEY_state ? "state" : "our"
+	                    ));
+	    }
 	    PL_in_my = (U16)tmp;
 	    s = skipspace(s);
 	    if (isIDFIRST_lazy_if(s,UTF)) {
-- 
2.4.5

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From zefram@fysh.org

See also [perl #121058].

-zefram

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @ap

* 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/>

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @ap

* 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/>

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @cpansprout

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 11, 2015

From @mauke

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).

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 12, 2015

From @ikegami

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;
  ...
}

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 12, 2015

From @ikegami

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;
...
}

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 25, 2015

From @mauke

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 f3106bc. This makes nested declarations an error.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 25, 2015

From [Unknown Contact. See original ticket]

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 f3106bc. This makes nested declarations an error.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 25, 2015

From @ikegami

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 f3106bc. This
makes nested declarations an error.

Is "local our" still allowed?

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Aug 25, 2015

From @ikegami

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 f3106bc. This
makes nested declarations an error.

Is "local our" still allowed?

Looked at the patch. It doesn't affect local at all.

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Nov 22, 2015

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented May 13, 2016

From @khwilliamson

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

@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented May 13, 2016

@khwilliamson - Status changed from 'pending release' to 'resolved'

@p5pRT p5pRT closed this May 13, 2016
@p5pRT

This comment has been minimized.

Copy link
Collaborator Author

@p5pRT p5pRT commented Jul 16, 2016

From @dcollinsn

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

@p5pRT p5pRT added the type-core label Oct 19, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.