Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations wOOdy-Soft on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Returning 2 values repetitively (as a list?)

Status
Not open for further replies.

wardy66

Programmer
Jun 18, 2002
102
AU
Hello. I wish to write a function that returns two values and can be used in a while loop or similar.

For example:
Code:
while( ($a, $b) = myfunc() ) {
    print "a=$a\tb=$b\n"
}

And this would print, eg,
Code:
a=1    b=2
a=6    b=9
a=1    b=10
until the function decided it had returned enough.

How would I return the two values and the end of the function?
How do I work out all my return values in the main part of the function and then return a list of lists (or whatever)??

It seems the "each" function does what I want when returning hash contents. But how to make my own function??

TIA
 
Basically you just return the values you want to as a list, as you might expect. Return the empty list to exit the while-loop. Here is a short example.
Code:
my ($a, $b) = (0,1);
while ( ($a, $b) = myfunc($a, $b) ) {
    print "a=$a\tb=$b\n";
}

sub myfunc {
    my ($m, $n) = @_;
    return () unless $m < 10;
    $m++;
    $n+=$n;
    return $m, $n;
}

jaa
 
Thanks, Justice

From your reply, I imagine that to write something that behaves like &quot;each&quot; will need to keep track of the number of calls to itself internally?

Your example is using the calling script to determine when to stop.

In my example, I need to determine the last entry internally to the subroutine.

I'm trying to process the output of another command but to keep things simple, imagine I wish to return the names of the files and their sizes one at a time to the caller until they've all been listed.

I am not accepting anything in @_ in my function. It knows what to do and how many entries are to be returned. It needs to tell the caller when it's finished.

You're example via the empty list () has woken me up to the way to make the loop end. But I'm still not sure how to make it return different values each time until the end, and then return ().

TIA
 
Even the 'each' command is passed something (the hash). But if the files are contained in the array @files then either of the following should work. The first is desctructive, the second is not.
Code:
sub myfunc {
    return () unless $numfiles;
    my $file = shift @files;
    my $size = -s $file;
    $numfiles = @files;
    return $file, $size;
}
Or
Code:
{
    my $counter = 0;
    sub myfunc {
        return () if $counter >= @files;
        my $file = $files[$counter];
        my $size = -s $file;
        $counter++;
        return $file, $size;
    }
}
The second sub is defined with $counter inside a block to make it private to the subroutine.

jaa
 
OK. I think I see the picture.

I really need some way of telling my function where it's up to and to do that I can either use:
1) lexically scoped variable around the sub
2) global variable.

I think my sub will need to decide if it's been called for the first time, do it's business, then return the first set of values.

If it's not the first time, return the next set of values or (), if they've all been returned.

Does this sound like a good summary?

Thanks a lot for the help.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top