1. related functions and subroutine. In this book, the function refers to the Perl built-in function, and subroutine refers to the user-defined function. In essence, the function and subroutine are the same thing. Unlike Pascal, functions in Pascal are different from subroutine. Functions return values while subroutine does not.
2. Defining a subroutine. Very simple:
-
Code: select all
-
sub marine {
$n += 1; # Global variable $n
print "Hello, sailor number $n!\n";
}
Use the keyword sub to define a subroutine named Marine. Note that the n variable in subroutine is a global variable, and how to define a local variable will be introduced later. The subroutine code in Perl can be placed anywhere in the Code. Generally, we place the subroutine code at the beginning (like C ). If we define two subroutine with the same name in the Code, the subroutine defined later will overwrite the previous subroutine.
3. Invoking a subroutine. Very simple. Use & to call a subroutine:
& Marine; # says hello, sailor number 1!
& Marine; # says hello, sailor Number 2!
& Marine; # says hello, sailor number 3!
& Marine; # says hello, sailor number 4!
4. return values. Perl is very different from other languages. Perl uses the return value/execution result of the last executed code in subroutine as the return value of the entire subroutine by default, unless we explicitly use the return statement.
-
Code: select all
-
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; # That's the return value
}
In the above example, the result of $ Fred + $ Barney is the return value of the entire subroutine. Therefore, pay attention to the last code to avoid errors in the return value, for example:
-
Code: select all
-
sub sum_of_fred_and_barney {
print "Hey, you called the sum_of_fred_and_barney subroutine!\n";
$fred + $barney; # That's not really the return value!
print "Hey, I'm returning a value now!\n"; # Oops!
}
A print statement is added at the end. Therefore, the return value of the entire subroutine changes to the return value of the print statement. When the print statement is successful, 1 (true) is returned ), 0 is returned if printing fails.
Let's look at this example again:
-
Code: select all
-
sub larger_of_fred_or_barney {
if ($fred > $barney) {
$fred;
} else {
$barney;
}
}
The return value of subroutine is the code executed in the last sentence, not the last code. Therefore, in the above example, subroutine returns the larger one of the two variables.
5. Arguments. This section describes how to define and use subroutine arguments. In Perl, parameters are passed to subroutine through the list method:
$ N = & MAX (10, 15); # This sub call has two parameters
In this case, the List (10, 15) is passed to Max subroutine. Perl will store the list in the default array @ _ of Perl, and then $ _ [0] is used. $ _ [1]... in this way, you can reference these arguments. Note that the variable here is actually _. Adding the @ symbol indicates referencing the entire list, and using the $ symbol indicates referencing an element in the list, which has been discussed in detail in chapter 3. In chapter 3, when we talk about the foreach structure, we also talk about the default variable $ _, which means the same as here.
-
Code: select all
-
sub max {
# Compare this to &larger_of_fred_or_barney
if ($_[0] > $_[1]) {
$_[0];
} else {
$_[1];
}
}
The Code becomes the above. However, the above Code is undoubtedly less readable, And the next section will explain how to change this situation. In addition, the above Code has another problem: What should I do if three parameters are provided when Max is called? Obviously, the third parameter is ignore. If a parameter is provided when Max is called, the second parameter is UNDEF.
OK. This section describes a very important thing: Each subroutine has its own @ _. For example, we call another subroutine (with parameters) in a subroutine ), the two subroutine have their own @ _, so we don't have to worry about calling other subroutine will affect our own @ _ array. Perl will automatically handle these tasks for us, so don't worry.
6. Private variable in subroutine ). Use the keyword "my" as follows:
-
Code: select all
-
sub max {
my($m, $n); # new, private variables for this block
($m, $n) = @_; # give names to the parameters
if ($m > $n) { $m } else { $n }
}
In the above example, we use the my keyword to define a list and then assign the parameter array @ _ to this list. Therefore, we can use $ m, $ n indicates two parameters. In addition, $ m and $ n are local variables of Max subroutine, which have nothing to do with others. No variables defined by my are used. Perl considers them global variable.
Note that $ m and $ n are not followed by semicolons In the last code. This is a rule of Perl, in the last sentence of the IF clause, you can leave no semicolons, but we can write them well at the standard point. The above example only shows that the code is very simple and can be written in one line, therefore, the semicolon is omitted.
By streamlining the code above, it becomes a very common code template:
-
Code: select all
-
sub max {
my($m, $n) = @_; # Name the subroutine parameters
if ($m > $n) { $m } else { $n }
}
7. variable-length parameter list. this section describes how to handle the variable length parameter list. That is to say, the maximum value of these parameters is given for Max implemented in this section. First of all, let's look at how we don't have this variable length structure. If we stipulate that Max can only accept two parameters, then Max subroutine may write as follows to enhance Fault Tolerance:
-
Code: select all
-
sub max {
if (@_ != 2) {
print "WARNING! &max should get exactly two arguments!\n";
}
# continue as before...
.
.
.
}
OK? If @ _ is used in scalar context, @ _ returns the number of parameters.
Then let's see how to limit the number of parameters:
-
Code: select all
-
$maximum = &max(3, 5, 10, 4, 6);
sub max {
my($max_so_far) = shift @_; # the first one is the largest yet seen
foreach (@_) { # look at the remaining arguments
if ($_ > $max_so_far) { # could this one be bigger yet?
$max_so_far = $_;
}
}
$max_so_far;
}
The above code is easy to understand. First, we use shift to retrieve the first element, and the list removes one element. Then, we use foreach to traverse the array cyclically and compare the elements one by one, then the max_so_far with the maximum value is given. In foreach, we do not explicitly define control variable. Therefore, we can use $ _ to represent control variable. This is what we learned in Chapter 3. With this code, you can process the variable-length parameter list.
The last question to consider is, can the above Code cope with the empty parameter list? Let's take a look. If it is an empty list, shift returns UNDEF, and the code in the foreach structure will not be executed once. The final returned result is UNDEF and OK. It seems that this is also the expected result. However, this is just an example. When writing any subroutine, we should consider that the parameter list is an empty list.