Learning Perl: 4.9. The return Operator
2010-07-21 17:34
288 查看
4.9. The return OperatorThe return operator immediately returns a value from a subroutine:my @names = qw/ fred barney betty dino wilma pebbles bamm-bamm /; my $result = &which_element_is("dino", @names); sub which_element_is { my($what, @array) = @_; foreach (0..$#array) { # indices of @array's elements if ($what eq $array[$_]) { return $_; # return early once found } } -1; # element not found (return is optional here) } This subroutine is being used to find the index of "dino" in the array @names. First, the my declaration names the parameters: there's $what, which is what we're searching for, and @array, an array of values to search within. That's a copy of the array @names in this case. The foreach loop steps through the indices of @array (the first index is 0, and the last one is $#array, as you saw in Chapter 3). Each time through the foreach loop, we check to see whether the string in $what is equal[*] to the element from @array at the current index. If it's equal, we return that index at once. This is the most common use of the keyword return in Perlto return a value immediately without executing the rest of the subroutine. [*] You noticed that we used the string equality test, eq, instead of the numeric equality test, = =, didn't you? What if we never found that element? In that case, the author of this subroutine has chosen to return -1 as a "value not found" code. It would be more Perlish, perhaps, to return undef in that case, but this programmer used -1. Saying return -1 on that last line would be correct, but the word return isn't needed. Some programmers like to use return every time there's a return value as a means of documenting that it is a return value. For example, you might use return when the return value is not the last line of the subroutine, such as in the subroutine &larger_of_fred_or_barney earlier in this chapter. It's not needed, but it doesn't hurt anything. However, many Perl programmers believe it's just an extra seven characters of typing. 4.9.1. Omitting the AmpersandA few rules govern when a subroutine call can omit the ampersand. If the compiler sees the subroutine definition before invocation or if Perl can tell from the syntax that it's a subroutine call, the subroutine can be called without an ampersand, like a built-in function. (But there's a catch hidden in those rules, as you'll see in a moment.)This means that if Perl can see that it's a subroutine call without the ampersand from the syntax alone, that's generally fine. That is, if you've got the parameter list in parentheses, it's got to be a function[ ] call: [ ] In this case, the function is the subroutine &shuffle. But it may be a built-in function as you'll see in a moment. my @cards = shuffle(@deck_of_cards); # No & necessary on &shuffle If Perl's internal compiler has seen the subroutine definition, that's generally okay, too; in that case, you can omit the parentheses around the argument list: sub division { $_[0] / $_[1]; # Divide first param by second } my $quotient = division 355, 113; # Uses &division This works because of the rule that parentheses may always be omitted except when doing so would change the meaning of the code. But don't put that subroutine declaration after the invocation, or the compiler won't know what the attempted invocation of division is all about. The compiler has to see the definition before the invocation to use the subroutine call as if it were a built-in. That's not the catch, though. The catch is this: if the subroutine has the same name as a Perl built-in, you must use the ampersand to call it. With an ampersand, you're sure to call the subroutine; without it, you can get the subroutine only if there's no built-in with the same name: sub chomp { print "Munch, munch!/n"; } &chomp; # That ampersand is not optional! Without the ampersand, we'd be calling the built-in chomp, even though we've defined the subroutine &chomp. So, the real rule to use is this one: until you know the names of all of Perl's built-in functions, always use the ampersand on function calls. That means that you will use it for your first hundred programs or so. But when you see someone else has omitted the ampersand in their own code, it's not necessarily a mistake; perhaps they know that Perl has no built-in with that name.[*] When programmers plan to call their subroutines as if they were calling Perl's built-ins, often when writing modules, they often use prototypes to tell Perl about the parameters to expect. Making modules is an advanced topic though; when you're ready for that, see Perl's documentation (in particular, the perlmod and perlsub documents) for more information about subroutine prototypes and making modules. [*] Then again, maybe it is a mistake; you can search the perlfunc and perlop manpages for that name to see if it's the same as a built-in. And Perl will usually be able to warn you about this when you have warnings turned on. |
相关文章推荐
- Learning Perl: 2.8. The chomp Operator
- Learning Perl: 5.2. Input from the Diamond Operator
- The "tr///" operator in Perl
- Perl Learning: 2.9. The while Control Structure
- perl the special operator
- Learning Perl: 4.8. The use strict Pragma
- Learning Perl: 4.10. Non-Scalar Return Values
- Perl Learning: 2.6. The if Control Structure
- Learning Perl: 3.6. The foreach Control Structure
- Discriminative Deep Metric Learning for Face Verification in the Wild(文献泛读)
- Misleading error message in PowerShell script: "Invalid assignment expression. The left hand side of an assignment operator need
- The provider did not return a ProviderManifestToken string. 的解决方法
- Inception系列3_Inception-v4:Inception-ResNet and the Impact of Residual Connections on Learning
- Learning the parts of object by NMF
- LightOJ - 1348 Aladdin and the Return Journey(树剖)
- Yoshua Bengio等大神传授:26条深度学习经验26 Things I Learned in the Deep Learning Summer School
- 14.9.10 The as operator
- Linear Programming Learning Notes (2) The Simplex Method
- 在线阅读Learning the vi Editor, Sixth Edition ,英文版
- Does the parameter type of the setter match the return type of the getter?