[comp.lang.perl] Subroutines Returning Null Arrays

jerbil@cit-vax.Caltech.Edu (Stainless Steel Gerbil [Joe Beckenbach]) (01/18/90)

	Is there a way to force a subroutine to return a null array?
Or. rather, I would like to do this:

	open( FILE, $file );
	@array = do subrtn( $stuff, $n, $nonsense );
	while ( $#array >= 0 ) {
		# fiddle $stuff and $nonsense
		# ...
	} continue {
		@array = do subrtn( $stuff, $n, $nonsense );
	}
	close( FILE );

I would be grateful if someone would present a way to do this, for the way
I'm trying to work things may be tripping a bug in my copy of perl, and I'm a
bit beyond my frustration point at the moment to try tracking down whether
it's a bug in perl or an error in my understanding of its behavior.  [Most
likely the latter, but after about four hours one begins to wonder....]

	Thanks ever so much.

		Joe Beckenbach

-- 
Joe Beckenbach		 jerbil@csvax.caltech.edu	VEGGIES FOREVER!
	Toto, kansasoseum nun est cognito.  -- Farley

hakanson@ogicse.ogc.edu (Marion Hakanson) (01/19/90)

In article <13395@cit-vax.Caltech.Edu> joe@cit-750.cs.caltech.edu (Joe Beckenbach) writes:
>
>	Is there a way to force a subroutine to return a null array?

Now that you mention it, I've been wondering about some odd behavior
related to that for awhile.  I have a workaround, and I forgot to track
it down further.  Here's the workaround:

while ( (@a = do subr()) && @a ) {
    # fiddle with @a
}

Now I just tracked it down further.  Here's a test program which
demonstrates the problem (perl 3.0, pl6, anyway -- I didn't notice
a patch in 7&8):

==========cut here===========
#!/usr/bin/perl

sub nsub1
{
  ();
}

sub nsub2
{
  return ();
}


@nr1 = do nsub1();
print "nr1 has $#nr1 elements.\n";

@nr2 = do nsub2();
print "nr2 has $#nr2 elements.\n";
==========cut here===========

Here's the output:

nr1 has -1 elements.
nr2 has 0 elements.

It turns out that $nr2[0] is empty, which is why my "workaround"
works.  Definitely looks like a bug to me, though.  Larry?

-- 
Marion Hakanson         Domain: hakanson@cse.ogi.edu
                        UUCP  : {hp-pcd,tektronix}!ogicse!hakanson

jerbil@cit-vax.Caltech.Edu (Stainless Steel Gerbil [Joe Beckenbach]) (01/19/90)

In my article <13395@cit-vax.Caltech.Edu> I write:
>	Is there a way to force a subroutine to return a null array?
> [... more stuff ...]

	Amazing what a good night's sleep will do for a body.  Found my
problem (of course it was my error, Larry!) and discovered the do { } while
construct, which simplified my script's logic to the point that I discovered
my errors.

		Joe
-- 
Joe Beckenbach		 jerbil@csvax.caltech.edu	VEGGIES FOREVER!
	Toto, kansasoseum nun est cognito.  -- Farley

jerbil@cit-vax.Caltech.Edu (Stainless Steel Gerbil [Joe Beckenbach]) (01/20/90)

In his article, Marion Hakanson <hakanson@ogicse.UUCP> produces a script
that reflects the problem I was having.  Bravo for locating the source of
my frustration on little evidence!

I've fetched a completely fresh copy for my machines and will try to cajole
my friends to keep in sync with it.  The copy that was causing the heartache
seems to have been 3p4 at best, from what little I can find.

Thanks again, all, for forgiving me my low signal:noise.

		Joe Beckenbach
-- 
Joe Beckenbach		 jerbil@csvax.caltech.edu	VEGGIES FOREVER!
	Toto, kansasoseum nun est cognito.  -- Farley

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/06/90)

In article <6712@ogicse.ogc.edu> hakanson@ogicse.UUCP (Marion Hakanson) writes:
: In article <13395@cit-vax.Caltech.Edu> joe@cit-750.cs.caltech.edu (Joe Beckenbach) writes:
: >
: >	Is there a way to force a subroutine to return a null array?
: 
: Now I just tracked it down further.  Here's a test program which
: demonstrates the problem (perl 3.0, pl6, anyway -- I didn't notice
: a patch in 7&8):
: 
: ==========cut here===========
: #!/usr/bin/perl
: 
: sub nsub1
: {
:   ();
: }
: 
: sub nsub2
: {
:   return ();
: }
: 
: 
: @nr1 = do nsub1();
: print "nr1 has $#nr1 elements.\n";
: 
: @nr2 = do nsub2();
: print "nr2 has $#nr2 elements.\n";
: ==========cut here===========
: 
: Here's the output:
: 
: nr1 has -1 elements.
: nr2 has 0 elements.
: 
: It turns out that $nr2[0] is empty, which is why my "workaround"
: works.  Definitely looks like a bug to me, though.  Larry?

This turned out to be a syntactic problem.  I had made return be a list
operator so that you can say

	return 1,2,3;

Unfortunately, like other list operators, if the next token was a left
paren, that and the matching paren were taken to delimit the entire function.
So
	return ()

transmogrified itself into

	(return);

and there went the null array.

This suggest several workarounds.  You can say any of

	return (());
	return ((),());
	return +();			# !!!
	return @nullarray;
	return 1..0;

The best solution, since

	return (123),456;

makes no sense, is to exempt "return" from the parenthesis rule for other
list operators, and have it ignore the parens.  It then will do what is
expected in almost every case.

Larry