Sometimes we don’t want to perform an action like printing out the total, but instead we want to return the total. We may also want to return a result to indicate whether what we were doing succeeded. This will allow us to say things like $sum_of_100 = total(1..100); There are two ways to do this: implicitly or explicitly. The implicit way is nice and easy—we just make the value we want to return the last thing in our subroutine: #!/usr/bin/perl w use strict; my $total = total(111, 107, 105, 114, 69); sub total { Running this code results in the following: $ perl total2.pl The last expression in the function doesn’t need to be a variable: we could use any expression. We can also return a list instead of a single scalar. Here is an example of returning a list from a function. Let’s convert a number of seconds to hours, minutes, and seconds. We pass the time in seconds into the subroutine, and it returns a threeelement list with the hours, minutes, and remaining seconds. #!/usr/bin/perl w use strict; my ($hours, $minutes, $seconds) = secs2hms(3723); sub secs2hms { This tells us that $ perl seconds.pl This program illustrates that just like a builtin function, when we’re expecting a subroutine to return a list, we can use an array or list of variables to collect the return values: my ($hours, $minutes, $seconds) = secs2hms(3723); Whensecs2hms()returns, this will be equivalent to my ($hours, $minutes, $seconds) = (1,2,3); And now let’s look at how the subroutine works. We start in the usual way:sub, the name, and a block. sub secs2hms { We have two variables to represent hours and minutes, and we read the parameters in from@_ if you don’t tellshift()which array to take data from, it’ll read from@_ if you’re in a subroutine or@ARGVif you’re not. Therefore, the first argument tosecs2hms(), 3723, is shifted into$seconds: my ($h,$m); Then the actual conversion: there are 3600 (60*60) seconds in an hour, and so the number of hours is the number of seconds divided by 3600. However, that’ll give us a floating point number—if we divided 3660 by 3600, we’d get 1.0341666. We’d rather have “one and a bit,” so we useint()to get the integer value, the “1” part of the division, and use the modulus operator to get the remainder; having dealt with the first 3600 seconds, we want to carry on looking at the next 123. $h = int($seconds/(60*60)); The second statement sets$secondsto$seconds % (60*60)—if it was 3723 before, it’ll be 123 now. The same goes for minutes: we divide to get “two and a bit,” and getting the remainder tells us that there are 3 seconds outstanding. Hence, our values are 1 hour, 2 minutes, and 3 seconds. $m = int($seconds/60); We return this just by leaving a list of the values as the last thing in the subroutine. ($h,$m,$seconds); The return Statement The explicit method of returning something from a subroutine is to sayreturn(...). The firstreturnstatement we come across will immediately return to the caller. For example: sub secs2hms { This also means we can have more than one return statement, and it’s often useful to do so. Please check back for the next part of this series.
blog comments powered by Disqus 






