merlyn@iwarp.intel.com (Randal L. Schwartz) (03/07/91)
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 | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Intel: putting the 'backward' in 'backward compatible'..."====/
rbj@uunet.UU.NET (Root Boy Jim) (03/07/91)
In article <1991Mar6.172554.14299@iwarp.intel.com> merlyn@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
tchrist@convex.COM (Tom Christiansen) (03/07/91)
From the keyboard of rbj@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 tchrist@convex.com convex!tchrist
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (03/07/91)
In article <124820@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: : In article <1991Mar6.172554.14299@iwarp.intel.com> merlyn@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
nagler@olsen.UUCP (Rob Nagler) (03/10/91)
In article <1991Mar6.172554.14299@iwarp.intel.com> merlyn@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 nagler@olsen.ch
tchrist@convex.COM (Tom Christiansen) (03/10/91)
From the keyboard of nagler@olsen.ch (Rob Nagler):
:In article <1991Mar6.172554.14299@iwarp.intel.com> merlyn@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
rbj@uunet.UU.NET (Root Boy Jim) (03/12/91)
In article <11706@jpl-devvax.JPL.NASA.GOV> lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) writes: >In article <124820@uunet.UU.NET> rbj@uunet.UU.NET (Root Boy Jim) writes: >: In article <1991Mar6.172554.14299@iwarp.intel.com> merlyn@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. -- [rbj@uunet 1] stty sane unknown mode: sane
tchrist@convex.COM (Tom Christiansen) (03/12/91)
From the keyboard of rbj@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
lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) (03/12/91)
In article <1991Mar09.200039.1484@convex.com> tchrist@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
rbj@uunet.UU.NET (Root Boy Jim) (03/12/91)
In article <1991Mar11.193009.19297@convex.com> tchrist@convex.COM (Tom Christiansen) writes:
?From the keyboard of rbj@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.
--
[rbj@uunet 1] stty sane
unknown mode: sane