Path: utzoo!attcan!uunet!tut.cis.ohio-state.edu!zaphod.mps.ohio-state.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: perl bug with $1, affected by subroutine call Message-ID: <7291@jpl-devvax.JPL.NASA.GOV> Date: 6 Mar 90 17:18:52 GMT References: Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 62 In article jbw@bucsf.bu.edu (Joe Wells) writes: : When the this short perl program is run: : : &one(&sub1); : &sub1; : : sub one { 1; } : sub sub1 { : if ('x' =~ m/(x)/) : { print "sub1 1: $1\n"; } : } : : I get this as output: : : sub1 1: : sub1 1: x : : Would anyone happen to know why $1 is not getting set properly in : &one(&sub1)? Yes. It's because in the first case you're calling sub1 in an array context, and in the second, a scalar context. Since the "if" is the last statement of the sub block, it has to be evaluated in the context that the subroutine was called. So the /(x)/ has it's array context behavior. Unfortunately, the subroutine then goes on to execute another "last" statement. It's something like a halting problem. : I've tried these variations, and they all work correctly: : : sub sub2 { : if (('x' =~ m/(x)/) && 1) : { print "sub2 1: $1\n"; } : } This works because you've forced the context to scalar by embedding in &&. : sub sub3 { : if ('x' =~ m/(x)/) : { print "sub3 1: $1\n"; } : 1; : } : sub sub4 { : 'x' =~ m/(x)/; : print "sub4 1: $1\n"; : } These work because the pattern match is no longer potentially in the last statement. I'm not sure what the moral of the story is. Certainly it would have been possible to design a less confusing return mechanism had I known at the beginning that subroutines would be returning array values. But that didn't come in till version 3. I suppose it would be possible to force conditional expressions to scalar context. Hmmm. I'll have to think about that... Meanwhile, if you want to be sure, just put an explicit return value (not to be confused with an explicit return). Just another organic Perl grower, Larry