Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!sdd.hp.com!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.jpl.nasa.gov (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Elegance: different aspect of next bug and elegent thingy.. Keywords: neato. Message-ID: <1991Mar13.233054.21347@jpl-devvax.jpl.nasa.gov> Date: 13 Mar 91 23:30:54 GMT References: <28041@fs2.NISC.SRI.COM> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 74 In article <28041@fs2.NISC.SRI.COM> cwilson@NISC.SRI.COM (Chan Wilson [Animal]) writes: : &input($labeltype) || {&Bzzzt; &WhatToPrint;} : ^^^^^^^^^^^^^^^^^^^^^^^^^ offending part : } A BLOCK is not an expression. To evaluate a BLOCK as part of an expression you have to put a do in front of it: &input($labeltype) || do {&Bzzzt; &WhatToPrint;} : Naturally, I discovered that I can't do that. So I rewrote a few : things: : : sub Bzzzt { : print stderr "\n\007 I need an answer here...\n\n"; : do $_[0]; : } : : : sub WhatToPrint { : [.....] : &input($labeltype) || &Bzzzt(WhatToPrint); : : : which had the _very_ interesting aspect of re-entering WhatToPrint at : the next executable line. It looks like this is another facet of the : next bug. Not really. This code is not doing what you want at all--it's looking for a file called WhatToPrint to evaluate, and not finding it, and returning. You should have said local($subname) = @_; do $subname(); The parens are required with do. I discourage people from calling subroutines with do any more for just this reason. & doesn't require parens: local($subname) = @_; &$subname; : But the elegent (IMHO, naturally) thing is what I came up with next. : I restored Bzzzt to original, and without really thinking, re-wrote : WhatToPrint to say: : : sub WhatToPrint { : [.....] : &input($labeltype) || &Bzzzt && &WhatToPrint; : : : which reads as "Do sub input with $labeltype. if 0 is returned, do : Bzzzt _AND_ do WhatToPrint", which is what I intended, but certainly : not what perl is interpreting it as. That's precisely what perl is interpreting it as, as long a Bzzzt returns a true value, which the print conveniently supplies. Remember that && has higher precedence than ||, so it naturally groups the same as &input($labeltype) || (&Bzzzt && &WhatToPrint); : Interesting, no? Seems to me this is a way around the `mumble || {foo}' : restriction... That's one way to do it. You also could have just said &input($labeltype) || (&Bzzzt, &WhatToPrint); But why use recursion when simple iteration will do? until (&WhatToPrint, &input($labeltype)) { &Bzzzt; } Larry