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 Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

foreach look - with sub routines? 2

Status
Not open for further replies.

garymgordon

Programmer
Apr 5, 2000
307
0
0
US
I see the following but don't understand fully ... why and how the line that says FOREACH is actually being handled.

sub sort_by_number
{
return $a <=> $b;
}

@array = (1,2,4,8,144,72,288);
foreach (sort sort_by_number (@array))
{
print (&quot;$_ &quot;);
}


Please help explain.

I understand that the sort function will sort the individual indexes from within the array and assign them individually to the variable of $_. But, how is the subroutine fitting in exactly how and where it is placed in the line that says:

foreach (sort sort_by_number (@array))


AND ...


I was under the impression that you were supposed to call a sub routine by adding a & in front of it. Is this not so? And, when would or would you not use the & in front of a sub routine to call it?


Thanks,
Gary
Gary M. Gordon, LLC
webmaster@garymgordon.com
Certified Web Developer ::
Application Programmer
 
You do not HAVE to use the & in front of subroutine names, and in this case it wants the NAME of the subroutine, not an actual subroutine CALL. The parentheses around @array are not there to indicate a subroutine call, but to turn the array into a LIST of values, which is what sort requires. What is happening is that, for each pair of VALUES (not indices) to be compared to sort the array, the named subroutine is called, with the two values passed as $a and $b. The sort subroutine should return -1, 0, or 1 depending on whether $a should be sorted as less than, equal to, or greater than, $b. In this case the <=> operator does this, assuming that $a and $b are NUMERIC. To do a string rather than numeric comparison use the cmp operator. You should not care WHAT the values of $a and $b are, only how they compare. If you print their values in each call to the sort subroutine you'll find that the value of $a or $b might be the same repeatedly until the sort finds it's proper position. The terminology &quot;sort subroutine&quot; is actually a misnomer. The subroutine does NOT actually sort anything, the sort function does that. The &quot;sort subroutine&quot; only tells the sort function how the two particular values it is comparing are to be ordered. It should probably be called a &quot;compare subroutine&quot; rather than a &quot;sort subroutine&quot;.

I know that was long-winded, but I hope it helps.
Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
nice answer. :)
also, note that it would not matter in this case if you had put an '&' in front of the subroutine's name, and it also doesn't matter whether or not the parantheses are put around the array. when arguments are passed into a subroutine, the values get flattened out into a list of scalars and put into @_.
in particular, that means that any modification a subroutine does on the values of an array passed in like that will not affect the actual array outside of the subroutine. to affect the actual array, you need to use references (but that's another lesson). this applies to the sort function. it doesn't modify the array you give it, but it returns a new array properly sorted which you should then assign to something. &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
I have to differ with you on the & question. According to my notes, sort does NOT like having the & on the front of the subroutine name. However, that was in version 5.4 and may have been fixed since then. Still, I think the semantics call for a subroutine NAME (or an anonymous subroutine declaration, but that's another lesson too) rather than a subroutine CALL, which would be the case if the & were there. All I know is the first time I tried using a sort subroutine I had the & there and it didn't work. When I took it off, it worked. Thus my notes strongly remind me to leave off the &.
Meddle not in the affairs of dragons,
For you are crunchy, and good with mustard.
 
hey, you're right. i was mixing things up in my memory. the way i usually call it is:[tt]
sort {&compare_sub} @array;[/tt]

i forgot that i was putting the {}'s around it for a reason. my way is probly even less efficient, as it's making an anonymous block for no reason.

i am *crunch*ed... :p &quot;If you think you're too small to make a difference, try spending a night in a closed tent with a mosquito.&quot;
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top