Weird response of "next" inside sub?

21 views
Skip to first unread message

Larry Wall

unread,
Mar 6, 1991, 6:47:20 PM3/6/91
to
In article <124...@uunet.UU.NET> r...@uunet.UU.NET (Root Boy Jim) writes:
: In article <1991Mar6.1...@iwarp.intel.com> mer...@iwarp.intel.com (Randal L. Schwartz) writes:
: >Watch this:
: >
: >Yow! The next exits the sub and cycles the outer "for" loop! (This
: >bit me in a program today.)
:
: I say leave it in. This is like catch/throw or setjmp/longjmp.
: As long as the subroutines are cleaned up ok, I'm all for it.

I think the subroutine is cleaned up okay, but it's still rather presumptous
of the subroutine to decide it was called from within a loop. And note that
"next" is more or less equivalent to a return if there is a return statement
in the subroutine, since return is implemented internally using a BLOCK.
You'd still be able to say "next FILE", or whatever.

Guess what this does:

sub foo {
return unless @_;
print "I say, ";
while ($_ = shift) {
redo _SUB_ if /^;$/;
print $_," ";
}
}
&foo(now,is,';',the,time);

Larry

Randal L. Schwartz

unread,
Mar 6, 1991, 12:25:54 PM3/6/91
to
Watch this:

for (1..5) {
print "before $_...\n";
&marine();
print "after $_...\n";
}

sub marine {
print "begin marine\n";
next; #################### look here
print "end marine\n";
}

which prints:

before 1...
begin marine
before 2...
begin marine
before 3...
begin marine
before 4...
begin marine
before 5...
begin marine

Yow! The next exits the sub and cycles the outer "for" loop! (This
bit me in a program today.)

I suspect that the "next" (as well as a last or redo) should be a
syntax error at this point. I can't see why loop control statements
should affect something out-of-scope.

Does anyone currently use this (mis-)feature in a positive way? If
not -- Larry, could you see about flagging this as an error?

sub a {next;} {&a; redo;} print "Just another Perl hacker,"
--
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III |
| mer...@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/

Root Boy Jim

unread,
Mar 6, 1991, 4:17:35 PM3/6/91
to
In article <1991Mar6.1...@iwarp.intel.com> mer...@iwarp.intel.com (Randal L. Schwartz) writes:
>Watch this:
>
>Yow! The next exits the sub and cycles the outer "for" loop! (This
>bit me in a program today.)

I say leave it in. This is like catch/throw or setjmp/longjmp.


As long as the subroutines are cleaned up ok, I'm all for it.

--
[rbj@uunet 1] stty sane
unknown mode: sane

Tom Christiansen

unread,
Mar 6, 1991, 4:40:41 PM3/6/91
to
From the keyboard of r...@uunet.UU.NET (Root Boy Jim):
:I say leave it in. This is like catch/throw or setjmp/longjmp.

:As long as the subroutines are cleaned up ok, I'm all for it.

Boo. Hiss. This is too easy to screw up, and not flexible
enough for exception handling. That's what eval/die give you.

--tom
--
I get so tired of utilities with arbitrary, undocumented,
compiled-in limits. Don't you?

Tom Christiansen tch...@convex.com convex!tchrist

Rob Nagler

unread,
Mar 9, 1991, 11:13:13 AM3/9/91
to
In article <1991Mar6.1...@iwarp.intel.com> mer...@iwarp.intel.com (Randal L. Schwartz) writes:
>Yow! The next exits the sub and cycles the outer "for" loop!
>Does anyone currently use this (mis-)feature in a positive way?

I often use the aformentioned feature as follows:

sub err { print STDERR "$f: $_[0]: @!\n"; next; }
for $f (@files) {
open(FILE, $f) || &err("open");
print FILE "something\n" || &err("print");
close(FILE) || &err("close");
}

You could turn this into one expression or put a next on every line.
However, I always take Larry's advice: "Perl is designed to give
you several ways to do anything, so consider picking the most
readable one." BTW, why doesn't "next $l" work?

$_='$_="Just another Perl";redo';{eval;$_.=' hacker,';}s,\S+\,,\U$&,,print;
Rob nag...@olsen.ch

Tom Christiansen

unread,
Mar 9, 1991, 3:00:39 PM3/9/91
to
From the keyboard of nag...@olsen.ch (Rob Nagler):

:In article <1991Mar6.1...@iwarp.intel.com> mer...@iwarp.intel.com (Randal L. Schwartz) writes:
:>Yow! The next exits the sub and cycles the outer "for" loop!
:>Does anyone currently use this (mis-)feature in a positive way?
:
:I often use the aformentioned feature as follows:

sigh. probably can't get rid of it then.
still, it gives me the willies.

:
:sub err { print STDERR "$f: $_[0]: @!\n"; next; }

you mean, $!, not @!, i think.

:for $f (@files) {


: open(FILE, $f) || &err("open");
: print FILE "something\n" || &err("print");
: close(FILE) || &err("close");
:}
:
:You could turn this into one expression or put a next on every line.
:However, I always take Larry's advice: "Perl is designed to give
:you several ways to do anything, so consider picking the most
:readable one." BTW, why doesn't "next $l" work?

(do you mean "next $f"?)

one answer is that next takes a label as an operand, not a scalar.
as for why this should be so, i dunno -- ask larry. :-)

--tom

Root Boy Jim

unread,
Mar 11, 1991, 2:09:24 PM3/11/91
to
In article <11...@jpl-devvax.JPL.NASA.GOV> lw...@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes:
>In article <124...@uunet.UU.NET> r...@uunet.UU.NET (Root Boy Jim) writes:
>: In article <1991Mar6.1...@iwarp.intel.com> mer...@iwarp.intel.com (Randal L. Schwartz) writes:
>: >Watch this:
>: >
>: >Yow! The next exits the sub and cycles the outer "for" loop! (This
>: >bit me in a program today.)
>:
>: I say leave it in. This is like catch/throw or setjmp/longjmp.
>: As long as the subroutines are cleaned up ok, I'm all for it.
>
>I think the subroutine is cleaned up okay, but it's still rather presumptous
>of the subroutine to decide it was called from within a loop. And note that
>"next" is more or less equivalent to a return if there is a return statement
>in the subroutine, since return is implemented internally using a BLOCK.

This is bad, because there no way to know this unless you
hack on perl's innards.

>You'd still be able to say "next FILE", or whatever.

This is almost equivalent to a catch/throw pair!

>Guess what this does:
>
sub foo {
return unless @_;
print "I say, ";
while ($_ = shift) {
redo _SUB_ if /^;$/;
print $_," ";
}
}
&foo(now,is,';',the,time);

It doesn't print: "I say, now is I say, the time" :-)

What are the rules for naming these blocks. Are they all called _SUB_?
Why not call them _FOO_, _BAR_, etc?

>Larry

Tom Christiansen sez:
>
>Boo. Hiss. This is too easy to screw up, and not flexible
>enough for exception handling. That's what eval/die give you.

As mentioned above, tis more or less catch/throw. And I'm
reluctant to use eval/die for this. Actually, eval/die is less
powerful than catch/throw or setjmp/longjmp, as there is only one
possible return point with the eval/die. Also, I am reluctant to
use eval often, even in LISP. I find the scoping slightly more
difficult to figure out.

Tom Christiansen

unread,
Mar 11, 1991, 2:30:09 PM3/11/91
to
From the keyboard of r...@uunet.UU.NET (Root Boy Jim):
:Also, I am reluctant to

:use eval often, even in LISP. I find the scoping slightly more
:difficult to figure out.

It's no different than at any other time: it's dynamic, which
means you can see something if your caller could. This is
what often confuses people, most of whom are used to lexical
scoping. Of course, once you bring pass-by-reference and
pass-by-name into the picture, you quickly find yourself caught
it a maze of twisty, turn pathways, all alike.

--tom

Root Boy Jim

unread,
Mar 12, 1991, 12:53:54 AM3/12/91
to
In article <1991Mar11.1...@convex.com> tch...@convex.COM (Tom Christiansen) writes:
?From the keyboard of r...@uunet.UU.NET (Root Boy Jim):
?:Also, I am reluctant to
?:use eval often, even in LISP. I find the scoping slightly more
?:difficult to figure out.
?
?It's no different than at any other time: it's dynamic, which
?means you can see something if your caller could. This is
?what often confuses people, most of whom are used to lexical
?scoping. Of course, once you bring pass-by-reference and
?pass-by-name into the picture, you quickly find yourself caught
?it a maze of twisty, turn pathways, all alike.

Actually, I prefer dynamic scoping over lexical scoping.
I guess I was trying to convince myself that using eval
produced a third kind of scope, but I guess not.

Larry Wall

unread,
Mar 11, 1991, 6:00:02 PM3/11/91
to
In article <1991Mar09....@convex.com> tch...@convex.COM (Tom Christiansen) writes:
: one answer is that next takes a label as an operand, not a scalar.

: as for why this should be so, i dunno -- ask larry. :-)

If I allowed "next $label" then I'd also have to allow "goto $label", and
I don't think you really want that... :-)

Besides, you can always say

eval "next $label";

:-)

Larry

Reply all
Reply to author
Forward
0 new messages