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

more given nonsense: what's a topicalizer? #11327

Open
p5pRT opened this issue May 9, 2011 · 15 comments
Open

more given nonsense: what's a topicalizer? #11327

p5pRT opened this issue May 9, 2011 · 15 comments

Comments

@p5pRT
Copy link

p5pRT commented May 9, 2011

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

Searchable as RT90182$

@p5pRT
Copy link
Author

p5pRT commented May 9, 2011

From tchrist@perl.com

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

In other words, it does the right thing, and then blows up.
The work around is​:

  use 5.010;
  while (<DATA>) {
  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 (<DATA>)

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
  .

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

From @ikegami

On Mon, May 9, 2011 at 9​:50 AM, tchrist1 <perlbug-followup@​perl.org> wrote​:

which is just ridiculous. What does it think

while (<DATA>)

is if not a topicalizer??

So what would qualify?

while ($_ = ...) { ... }
while (defined($_ = ...)) { ... }
while (($_ = ...) RELOP ...) { ... }
while (..., $_ = ..., ...) { ... }
while (..., defined($_ = ...), ...) { ... }
while (..., ($_ = ...) RELOP ..., ...) { ... }

Same for C<for(;;)>?

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

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

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

From tchrist@perl.com

"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 (<DATA>)

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

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

From @ikegami

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.

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

From tchrist@perl.com

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

@p5pRT
Copy link
Author

p5pRT commented May 10, 2011

From @ap

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

@p5pRT
Copy link
Author

p5pRT commented May 11, 2011

From @ikegami

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<break> and finds neither C<given>
or C<foreach> (for C<next>).

It could start looking for any loop. Is there any problems (compatibility
issues) with doing so?

@p5pRT
Copy link
Author

p5pRT commented May 12, 2011

From @ap

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

@p5pRT
Copy link
Author

p5pRT commented May 12, 2011

From tchrist@perl.com

* 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

@p5pRT
Copy link
Author

p5pRT commented May 15, 2011

From @cpansprout

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.

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2012

From perl-diddler@tlinx.org

Created by perl-diddler@tlinx.org

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&gt;=$#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?)

Perl Info

Flags:
    category=core
    severity=low

This perlbug was built using Perl 5.12.3 - Fri May  6 13:31:41 UTC 2011
It is being executed now by  Perl 5.12.3 - Fri May  6 13:26:30 UTC 2011.

Site configuration information for perl 5.12.3:

Configured by abuild at Fri May  6 13:26:30 UTC 2011.

Summary of my perl5 (revision 5 version 12 subversion 3) configuration:
   
  Platform:
    osname=linux, osvers=2.6.36, archname=x86_64-linux-thread-multi
    uname='linux build33 2.6.36 #1 smp 2011-02-21 10:34:10 +0100 x86_64 x86_64 x86_64 gnulinux '
    config_args='-ds -e -Dprefix=/usr -Dvendorprefix=/usr -Dinstallusrbinperl -Dusethreads -Di_db -Di_dbm -Di_ndbm -Di_gdbm -Duseshrplib=true -Doptimize=-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack- protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe -Accflags=-DPERL_USE_SAFE_PUTENV'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-fmessage-length=0 -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector -funwind-tables -fasynchronous-unwind-tables -g -Wall -pipe',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DPERL_USE_SAFE_PUTENV -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector'
    ccversion='', gccversion='4.5.1 20101208 [gcc-4_5-branch revision 167585]', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -L/usr/local/lib64 -fstack-protector'
    libpth=/lib64 /usr/lib64 /usr/local/lib64
    libs=-lm -ldl -lcrypt -lpthread
    perllibs=-lm -ldl -lcrypt -lpthread
    libc=/lib64/libc-2.11.3.so, so=so, useshrplib=true, libperl=libperl.so
    gnulibc_version='2.11.3'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-rpath,/usr/lib/perl5/5.12.3/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC', lddlflags='-shared -L/usr/local/lib64 -fstack-protector'

Locally applied patches:
    


@INC for perl 5.12.3:
    /usr/lib/perl5/site_perl/5.12.3/x86_64-linux-thread-multi
    /usr/lib/perl5/site_perl/5.12.3
    /usr/lib/perl5/vendor_perl/5.12.3/x86_64-linux-thread-multi
    /usr/lib/perl5/vendor_perl/5.12.3
    /usr/lib/perl5/5.12.3/x86_64-linux-thread-multi
    /usr/lib/perl5/5.12.3
    .


Environment for perl 5.12.3:
    HOME=/home/law
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LC_CTYPE=en_US.UTF-8
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=.:/sbin:/usr/local/sbin:/opt/lsb/bin:/home/law/bin:/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin:/usr/lib/qt3/bin:/usr/sbin
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2012

From @ikegami

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<when> 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 (...; ...; ...) >>).

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2012

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

@p5pRT
Copy link
Author

p5pRT commented Jan 22, 2012

From @cpansprout

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<when> 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants