Open p5pRT opened 13 years ago
When you run this:
use 5.010; while (\) { when (/foo/) { say "meta" } when (/\d/) { say "number" } default { say "other" } } __END__ fee fie 23 skiddoo foo fum
You get:
other Can't use when() outside a topicalizer at /tmp/s0 line 5\, \ line 1. Exit 255
In other words\, it does the right thing\, and then blows up.
The work around is:
use 5.010; while (\) { eval { # ...protect the loop from senseless nannying when (/foo/) { say "meta" } when (/\d/) { say "number" } default { say "other" } } } __END__ fee fie 23 skiddoo foo fum
Which correctly prints:
other number meta
which is just ridiculous. What does it think
while (\)
is if not a topicalizer??
BTW\, this *does* work correctly in Perl 6.
--tom
Summary of my perl5 (revision 5 version 12 subversion 3) configuration:
Platform:
osname=openbsd\, osvers=4.4\, archname=OpenBSD.i386-openbsd
uname='openbsd chthon 4.4 generic#0 i386 '
config_args='-des'
hint=recommended\, useposix=true\, d_sigaction=define
useithreads=undef\, usemultiplicity=undef
useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef
use64bitint=undef\, use64bitall=undef\, uselongdouble=undef
usemymalloc=n\, bincompat5005=undef
Compiler:
cc='cc'\, ccflags ='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'\,
optimize='-O2'\,
cppflags='-fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
ccversion=''\, gccversion='3.3.5 (propolice)'\, gccosandvers='openbsd4.4'
intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234
d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12
ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8
alignbytes=4\, prototype=define
Linker and Libraries:
ld='cc'\, ldflags ='-Wl\,-E -fstack-protector -L/usr/local/lib'
libpth=/usr/local/lib /usr/lib
libs=-lgdbm -lm -lutil -lc
perllibs=-lm -lutil -lc
libc=/usr/lib/libc.so.48.0\, so=so\, useshrplib=false\, libperl=libperl.a
gnulibc_version=''
Dynamic Linking:
dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags=' '
cccdlflags='-DPIC -fPIC '\, lddlflags='-shared -fPIC -L/usr/local/lib -fstack-protector'
Characteristics of this binary (from libperl): Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP USE_LARGE_FILES USE_PERLIO USE_PERL_ATOF Built under openbsd Compiled at Feb 14 2011 07:32:03 %ENV: PERL_UNICODE="SA" @INC: /usr/local/lib/perl5/site_perl/5.12.3/OpenBSD.i386-openbsd /usr/local/lib/perl5/site_perl/5.12.3 /usr/local/lib/perl5/5.12.3/OpenBSD.i386-openbsd /usr/local/lib/perl5/5.12.3 /usr/local/lib/perl5/site_perl/5.11.3 /usr/local/lib/perl5/site_perl/5.10.1 /usr/local/lib/perl5/site_perl/5.10.0 /usr/local/lib/perl5/site_perl/5.8.7 /usr/local/lib/perl5/site_perl/5.8.0 /usr/local/lib/perl5/site_perl/5.6.0 /usr/local/lib/perl5/site_perl/5.005 /usr/local/lib/perl5/site_perl .
On Mon\, May 9\, 2011 at 9:50 AM\, tchrist1 \perlbug\-followup@​perl\.org wrote:
which is just ridiculous. What does it think
while (\)
is if not a topicalizer??
So what would qualify?
while ($_ = ...) { ... } while (defined($_ = ...)) { ... } while (($_ = ...) RELOP ...) { ... } while (...\, $_ = ...\, ...) { ... } while (...\, defined($_ = ...)\, ...) { ... } while (...\, ($_ = ...) RELOP ...\, ...) { ... }
Same for C\<for(;;)>?
The RT System itself - Status changed from 'new' to 'open'
"Eric Brine via RT" \perlbug\-followup@​perl\.org wrote on Tue\, 10 May 2011 09:41:45 PDT:
which is just ridiculous. What does it think
while (\)
is if not a topicalizer??
So what would qualify?
while ($_ = ...) { ... } while (defined($_ = ...)) { ... } while (($_ = ...) RELOP ...) { ... } while (...\, $_ = ...\, ...) { ... } while (...\, defined($_ = ...)\, ...) { ... } while (...\, ($_ = ...) RELOP ...\, ...) { ... }
Same for C\<for(;;)>?
In Perl6\, when works wherever $_ is around to test against. This seems perfectly straightforward. I don't know how this very complicated set of behaviors found their way into Perl5.
--tom
In Perl6\, when works wherever $_ is around to test against.
$_ is always around in Perl5\, even when there's nothing to next/break out of.
Eric Brine \ikegami@​adaelis\.com wrote on Tue\, 10 May 2011 13:01:44 EDT:
In Perl6\, when works wherever $_ is around to test against.
$_ is always around in Perl5\, even when there's nothing to next/break out of.
Just let them try. :)
I would be quite happy to have it in
while (\<>) { ... when ...; ... when ...; ... when ...; ... when ...; }
--tom
* tchrist1 \perlbug\-followup@​perl\.org [2011-05-09 15:55]:
which is just ridiculous. What does it think
while \(\<DATA>\)
is if not a topicalizer??
BTW\, this *does* work correctly in Perl 6.
I think this is the consequence of `break` being added as a `given`-specific special form of `next`. I am guessing wildly that the thought behind adding `break` was that doing `next` inside `given` should abort the iteration of a surrounding loop instead of just the `given` block\, maybe in (mistaken) analogy to what `next` does inside `if`. At least that is the only plausible reason I can imagine why someone thought `break` was a good idea.
And once you have `break` you have to come up with a special set of rules for how `when` will examine scope\, which gets you into this mess.
Needless to say I donât see the point since itâs possible to do `next LABEL` and this is how one has always been supposed to break out of nested loops. Half amusing and half maddening is that `given` has *extra* special rules to do `next` instead of `break` when inside a `foreach` rather than a `given`.
I think `when` shouldnât just do an implicit `next` in all cases. That already has clear rules about what it will complain of\, and it would make `when` far more useful.
In fact if `when` lost the implicit smart match and became *nothing else/more* than an `if` with implicit `next`\, Iâd find it *even better*. Thatâs probably not feasible\, alas. But we could at least lose this `break` silliness.
Regards\, -- Aristotle Pagaltzis // \<http://plasmasturm.org/>
On Tue\, May 10\, 2011 at 3:10 PM\, Tom Christiansen \tchrist@​perl\.com wrote:
Eric Brine \ikegami@​adaelis\.com wrote on Tue\, 10 May 2011 13:01:44 EDT:
In Perl6\, when works wherever $_ is around to test against.
$_ is always around in Perl5\, even when there's nothing to next/break out of.
Just let them try. :)
That's what's happening. It's trying to C\
It could start looking for any loop. Is there any problems (compatibility issues) with doing so?
* Aristotle Pagaltzis \pagaltzis@​gmx\.de [2011-05-11 00:15]:
I think `when` shouldnât just do an implicit `next` in all cases.
No\, I donât think that\, I just ended up saying it because of too much editing. I think it *should* just do an implicit `next`.
Regards\, -- Aristotle Pagaltzis // \<http://plasmasturm.org/>
* Aristotle Pagaltzis \pagaltzis@​gmx\.de [2011-05-11 00:15]:
I think `when` shouldnâÂÂt just do an implicit `next` in all cases.
No\, I donâÂÂt think that\, I just ended up saying it because of too much editing. I think it *should* just do an implicit `next`.
Me\, I was surprised it didn't.
--tom
On Mon May 09 06:50:09 2011\, tom christiansen wrote:
When you run this:
use 5\.010; while \(\<DATA>\) \{ when \(/foo/\) \{ say "meta" \} when \(/\\d/\) \{ say "number" \} default \{ say "other" \} \} \_\_END\_\_ fee fie 23 skiddoo foo fum
You get:
other Can't use when\(\) outside a topicalizer at /tmp/s0 line 5\, \<DATA>
line 1. Exit 255
Itâs even stranger than you think:
$ perl -E 'given(1) { for my $x (2) { break } } warn ok' ok at -e line 1. $ perl -E 'given(1) { for (2) { break } }' Can't "break" in a loop topicalizer at -e line 1.
It seems like perl is being a bit over zealous about it's policing the use of "when". Technically\, a topicalizer is something that defines the "topic" (or subject).. like given and when automatically use '$_'. But I can write my own 'topicalizer' that funnels data into $_ -- trivially.
A prime example would be 'when(\<>){}'\, where you process lines like /filt/ and do {xxyz; continue}; /filter/ and do {xxyz+1; next}; ...
Sometimes an if/elsif/else/ construct is useful\, but only if you don't have exceptions.
Another example I ran into today:
In a trivial prog\, I had a foreach loop to parse args.
Later had an arg that took a param -- how to skip a 'each'\,
in foreach? Well:
for ($_=$ARGV[$n = 0]; $n\<@ARGV; $_=$ARGV[$n]) { ... when(arg (-rc) with param) { my $m=$n+1; $m>=$#ARGV or die "-rc needs param\n"; $rc=$ARGV[$m]; ++$n } when (next case)... }
--- Course now\, this doesn't work -- to make it work I'll have to add an extra 2 lines inside the forloop\, which I hope won't have any side effects...i.e.
for ($_=each(@ARGV); $_\<=lastmem(@ARGV); $_=next(@ARGV) ) { given ($_) { when ... ... } }
Can someone explain to me the rational for the interpreter to 'restrict' the usage of 'when' to a smaller subset than where 'last/next/continue' would work or why it not working in the same places shouldn't be considered a bug?
Thanks!
(p.s. can you think of any side effects of tossing in the
extra given{} in the for loop to satisfy the interp's warnings?)
On Sun\, Jan 22\, 2012 at 12:21 AM\, Linda Walsh \perlbug\-followup@​perl\.orgwrote:
Can someone explain to me the rational for the interpreter to 'restrict' the usage of 'when' to a smaller subset than where 'last/next/continue' would work
C\
The RT System itself - Status changed from 'new' to 'open'
On Sat Jan 21 22:11:07 2012\, ikegami@adaelis.com wrote:
On Sun\, Jan 22\, 2012 at 12:21 AM\, Linda Walsh \<perlbug- followup@perl.org>wrote:
Can someone explain to me the rational for the interpreter to 'restrict' the usage of 'when' to a smaller subset than where 'last/next/continue' would work
C\
was primary written to compare to $_ (e.g. C\<\< when ("foo") )\, so it's only allowed in flow control statements that set $_ (e.g. C\<\< for (...) >>\, but not C\<\< for my $x (...) >> and C\<\< for (...; ...; ...) ).
Except even that doesnât work properly. Since this is basically the same issue\, Iâm merging it with #90182.
--
Father Chrysostomos
This program was provided by the OP who ran it against perl-5.12.3.
$ $ cat $P5P_DIR/gh-11327-topicalizer.pl
use 5.010;
# https://github.com/Perl/perl5/issues/11327
# originally: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=90182
while (<DATA>) {
when (/foo/) { say "meta" }
when (/\d/) { say "number" }
default { say "other" }
}
__END__
fee fie
23 skiddoo
foo fum
The output originally reported was:
other
Can't use when() outside a topicalizer at /tmp/s0 line 5, <DATA> line 1.
Exit 255
Let's see what happens with later versions of Perl.
$ perlbrew use perl-5.14.4
$ perl /tmp/gh-11327-topicalizer.pl
other
Can't use when() outside a topicalizer at /tmp/gh-11327-topicalizer.pl line 8, <DATA> line 1.
$ perlbrew use perl-5.16.3
[perl] 2366 $ perl /tmp/gh-11327-topicalizer.pl
other
Can't "default" outside a topicalizer at /tmp/gh-11327-topicalizer.pl line 8, <DATA> line 1.
So the output changed between perl-5.14 and perl-5.16.
$ perlbrew use perl-5.18.4
$ perl /tmp/gh-11327-topicalizer.pl
when is experimental at /tmp/gh-11327-topicalizer.pl line 6.
when is experimental at /tmp/gh-11327-topicalizer.pl line 7.
other
Can't "default" outside a topicalizer at /tmp/gh-11327-topicalizer.pl line 8, <DATA> line 1.
A warning appeared in perl-5.18. The output above is what still appears in perl-5.38 and is scheduled to appear in perl-5.40 as well.
Given that the smartmatch given/when
syntax will be removed from the language after the release of perl-5.40, s there any reason to keep this 13-year-old ticket open?
No. Without when
, this issue is moot.
No. Without
when
, this issue is moot.
Okay. I'll self-assign for the purpose of closing it when we complete the removal of when
. Thanks.
No. Without
when
, this issue is moot.Okay. I'll self-assign for the purpose of closing it when we complete the removal of
when
. Thanks.
While given/when/smartmatch has been removed from blead, the decision has been controversial. So this ticket should remain open until the issue is definitively resolved.
Migrated from rt.perl.org#90182 (status was 'open')
Searchable as RT90182$