You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

443 lines
25 KiB

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>My Learning Website</title>
<link href="/styles/styles.css" rel="stylesheet" type="text/css">
<link href="/programming/styles/styles.css" rel="stylesheet" type="text/css">
<!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
<![endif]-->
</head>
<body>
<div class="banner">
<h1 class="courselink">Perl 5 Essential Traning</h1>
<h2 class="lecturer">LinkedIn Learning : Bill Weinman</h2>
<h2 class="episodetitle">Functions</h2>
</div>
<article>
<h2 class="sectiontitle">Understanding Functions</h2>
<p>Like most languages, Perl supports user-defined functions. The official Perl documentation uses the words Function and Subroutine interchangeably. This is in contrast with other programming languages where the distinction is made that a function is something that returns some value, usually only one value. Perl does not make this distinction.</p>
<p>The general syntax of a function is the keyword, sub, followed by the function name and a block of code in curly brackets as shown in figure 82.</p>
<pre class="inset">
1. sub function_name {
2. say “This is a function”;
3. }</pre>
<p class="caption">Figure 82 - the general syntax of a function (or subroutine) in Perl</p>
<p>To pass parameters to a function, we use the default array variable that was mentioned earlier, @_ and we can retrieve the values with shift. So, shift will retrieve parameters from the array (if an array is not specified) as shown in figure 83.</p>
<pre class="inset">
1. sub function_name {
2. my $x = shift;
3. …
4. }</pre>
<p class="caption">Figure 83 - retrieving a parameter from the default array with shift</p>
<p>We use the return keyword to return a value from a function and this can be a scalar value or a list. This is demonstrated in figure 84.</p>
<pre class="inset">
1. sub function_name {
2. …
3. return $x;
4. }</pre>
<p class="caption">Figure 84 - returning a value from a function</p>
<h2 class="sectiontitle">Defining and Calling Functions</h2>
<p>Figure 85 shows the code for hello.pl which has been modified to use a function called hello which simply outputs the message, ‘This is the hello function.’</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello();
8.
9. sub hello {
10. say 'This is the hello function';
11. }</pre>
<p class="caption">Figure 85 - hello.pl demonstrating the creation and call of a function</p>
<p>We can see, here, that the function is defined in lines 9 and 11 and is called on line 7. Note that this is in contrast with C which cannot call a function it doesn’t know about yet. In Perl, there is no requirement to declare or define the function before it can be called.</p>
<h2 class="sectiontitle">Calling a Function with Arguments</h2>
<p>The code in figure 86 is similar to the hello.pl code shown in figure 85. However, this time we are passing an argument over to the function.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello('Philip');
8.
9. sub hello {
10. my $name = shift;
11. say "Say hello to: $name";
12. }</pre>
<p class ="caption">Figure 86 - func.pl which demonstrates the passing of an argument to the function</p>
<p>Note that in line 7 where we are calling the function, we have placed a parameter in the parentheses. This is extracted inside the function using shift on line 10. On line 11, we use this parameter to output a personalised message.</p>
<p>An interesting feature of Perl compared to other programming languages is that we have not specified either a number or type for the argument(s) that are going to be passed to the function. To demonstrate this, the code in line 87 uses the same function with multiple arguments.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello('Fred', 'Barney', 'Wilma', 'Betty');
8.
9. sub hello {
10. my $a = shift;
11. my $b = shift;
12. my $c = shift;
13. my $d = shift;
14. say "Say hello to $a, $b, $c and $d.";
15. }</pre>
<p class="caption">Figure 87 - using the function with multiple arguments</p>
<p>We can see in line 7 that there are four arguments being passed to the function. We also have four corresponding shift statements to extract the parameters in sequence. The arguments are output with a say statement on line 14.</p>
<p>We can also make this a little easier by assigning the contents of the default array to our four variables as shown in figure 88.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello('Fred', 'Barney', 'Wilma', 'Betty');
8.
9. sub hello {
10. my ($a, $b, $c, $d) = @_;
11. say "Say hello to $a, $b, $c, $d";
12. }</pre>
<p class="caption">Figure 88 - again, using the function with multiple arguments without having to use the shift statement for each argument</p>
<p>There is a drawback with this approach, of course. We have matched our shift statements to each of the corresponding arguments, so this is fine when we know in advance how many arguments are going to be passed to the function.</p>
<p>However, we are passing an array to the function. Rather than use the shift statement to extract the parameters, we can simply use a foreach loop to output each parameter and this is demonstrated in the code shown in figure 89.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello('Fred', 'Barney', 'Wilma', 'Betty');
8.
9. sub hello {
10. say "Say hello to:";
11. say foreach @_;
12. }</pre>
<p class="caption">Figure 89 - the function, func.pl, called with four arguments again, but written in such a way that it would output any arbitrary number of arguments</p>
<p>This has its own drawback, of course, because we don’t know in advance how many arguments we are going to receive in the function so we can’t neatly format the output as we did in the example in figures 87 and 88. At least, not as easily. I guess that the solution here would be to use a scalar variable to determine the size of the default array and then use a for loop to output all of the elements except the last two and then have specials output statement for those last two element.</p>
<p>Another option would be to use pop to remove the last two elements then use a foreach loop to output the remaining array elements followed by a special output statement for the last two elements. One possible solution is given in figure 90.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. hello('Fred', 'Barney', 'Wilma', 'Betty');
8.
9. sub hello {
10. my $last = pop @_;
11. my $pen = pop @_;
12. print "Hello to ";
13. foreach my $s ( @_ ) {
14. print "$s";
15. print ", ";
16. }
17. print $pen;
18. say " and $last.";
19. }</pre>
<p class="caption">Figure 90 - amending the solution so that we can output a nicely formatted hello message for any number of arguments</p>
<p>Note that the code in figure 90 will work perfectly well with two arguments but will result in untidy output if less than two arguments are provided. Actually, I was a little surprised by that because I would have expected an error given that we are using pop on an empty array if there are less than two arguments. It seems to simply return an empty string (or just nothing) if the array is empty so it doesn’t error, but it will give you output such as</p>
<p class="inset">Hello to and Philip.</p>
<p>or</p>
<p class="inset">Hello to and</p>
<p>One final point to make is that we can declare a variable beforehand and pass that to the function call as in</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. my @array= qw ( Fred Barney Wilma Betty );
8. hello(@array);
9.
10. sub hello {
11. my $last = pop @_;
12. my $pen = pop @_;
13. print "Hello to ";
14. foreach my $s ( @_ ) {
15. print "$s";
16. print ", ";
17. }
18. print $pen;
19. say " and $last.";
20. } </pre>
<p class="caption">Figure 91 - passing an array as an argument to a function</p>
<p>We can also combine literal strings and arrays in a function call with something like</p>
<p class="inset">hello(‘Philip’, @array);</p>
<p>There’s not really any difference between a literal string and an array of strings in a call like this. Note that from the functions perspective, it receives all these arguments in a single array regardless of how they are specified in the call.</p>
<h2 class="sectiontitle">Locally Scoped Variables</h2>
<p>The code in figure 91 includes five variable declarations. We have an array declared on line 7 and scalar variables declared on lines 11, 12 and 15. In each case, the name of the variable is preceded by the keyword my. The purpose of my is to give the variable lexical scope. This is similar to variable scope in other languages and, as you might expect, the scope exists within the block of code in which the variable is declared.</p>
<p>It is important to remember that although we generally think of a block of code as being some snippet of code which is enclosed in curly braces, the file itself is a block of code. To illustrate this, let’s look at the simple piece of code shown in figure 92.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # block.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. my $x = 42;
8.
9. func ();
10.
11. sub func {
12. say "x is $x";
13. }</pre>
<p class="caption">Figure 92 - block.pl demonstrating the lexical scope of a variable</p>
<p>In this example, in addition to the file itself, we have one block of code which is the body of the function and one variable.</p>
<p>The variable is not declared in the function so it has lexical scope based on where it was declared, that is the file. So, we can use it anywhere within the file and that includes within the function.</p>
<p>As a result, the output we get when we run this is</p>
<p class="inset">x is 42</p>
<p>Now, let’s look at the code, slightly modified, in figure 93.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # block.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. my $x = 42;
8.
9. func();
10.
11. sub func {
12. my $x = 192;
13. say "x is $x";
14. }</pre>
<p class="caption">Figure 93 - block.pl with the variable, $x, declared twice</p>
<p>This time, we have declared $x inside the function and left the original declaration on line 7. When we run this, the output is</p>
<p class="inset">x is 192</p>
<p>This is because my gives the variable local scope. On line 13, we are using a variable called $x and Perl checks whether there is a variable with local scope inside the function. For the code in figure 93, it finds this variable which has been initialized with a value of 192 so that is the value that is output.</p>
<p>If it doesn’t find the variable inside the function, it will look in the block of code that contains the function and if necessary, the block of code that contains that block of code and so on until it either finds a valid variable declaration or it doesn’t find it (in which case, you will get an error).</p>
<p>This is, I guess, similar to what happens when you call a method on a class in an object oriented language where the compiler (or interpreter) will look for the method in the class, then the parent class and so on right up to the class at the top of the hierarchy, and again, you will get an error if it isn’t found.</p>
<p>In the code shown in figure 92, the variable wasn’t found in the function. The block of code that contains the function is the file itself and the variable was found there (initialized with a value of 42) and so that is the value we saw in the output.</p>
<p>Now, let’s look at one final version of the code in figure 94.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # block.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. my $x = 42;
8.
9. func();
10.
11. sub func {
12. my $x = 192;
13. say "x is $x";
14. }
15. say "x is $x";</pre>
<p class="caption">Figure 94 - block.pl as shown in figure 93 but with the value of x accessed outside of the function</p>
<p>In this example, we have output the value of x on line 13 and again on line 15. The output we get is</p>
<pre class="inset">
x is 192
x is 42</pre>
<p>Here, we can see that the output statement inside the function (line 13) has accessed the variable function on line 12. The output statement on line 15 is outside the function, so it cannot access the variable declaration on line 12. However, it can access the variable declaration on line 7 so the program works, but although the variable name is the same in both output statements, they are accessing different variables and so we get two different values in the output.</p>
<p>If we delete line 7 and run the code again, the output we get is</p>
<pre class="inset">
Global symbol "$x" requires explicit package name (did you forget to declare "my $x"?) at block.pl line 14.
Execution of block.pl aborted due to compilation errors.</pre>
<p>Now, there is no variable called $x available outside of the function and so we get the error when we try to access it on line 14 (this is line 15 in figure 94).</p>
<p>We could sum up by saying that a variable can only be accessed if it is declared within the block of code from which it is being accessed or a code block that contains the block of code from which it is being accessed.</p>
<p>Perl also has a keyword, local and the use of this is demonstrated in figure 95.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # block.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. our $x = 42;
8. func();
9.
10. say "My x is $x";
11.
12. sub func {
13. local $x = 192;
14. say "Local x is $x";
15. }</pre>
<p class="caption">Figure 95 - the same code as shown in figure 94 but declaring the variable as local</p>
<p>Note that if we declare the variable with my on line 7 and local inside the function, on line 13, we will see the following error.</p>
<p>Can't localize lexical variable $x at block.pl line 13.</p>
<p>There is some information on this error on Stack Overflow under the question, <a href="https://stackoverflow.com/questions/20176433/why-cant-localize-lexical-variable-in-perl">Why can't localize lexical variable in Perl?</a> I expected this to work, but as we can see in the error, we can’t use local inside the function when it has been declared with my outside the function. We can fix this by declaring the variable with our on line 7 and this gives us the output</p>
<pre class="inset">
Local x is 192
My x is 42</pre>
<p>If we declared both variables with my, the result is exactly the same</p>
<pre class="inset">
Local x is 192
My x is 42</pre>
<p>This implies that my and local (or more accurately, my/my and our/local) do exactly the same thing. They don’t. The result is the same, but local is exactly doing something slightly different in ‘localizing’ the variable.</p>
<p>In the original version of the code shown in figure 94, we are declaring two different variables which happen to have the same name. In the version shown in figure 95, we declared the variable with our outside the function so that we could localize it inside the function.</p>
<p>Now, what local does is to temporarily assign a different value to $x and use that value inside the function. It then reassigns the original value (by which I mean whatever value $x held when the function was called) to $x. So, it seems that they are two separate variables but it is actually just one variable in this scenario.</p>
<p>The local keyword is a bit of a holdover from Perl 4 and it has been largely superseded by my. The my keyword was introduced in Perl 5 which is well over 20 years old now so you will most likely only ever see local (and our) in very old code but there is no real reason to include it in code written today.</p>
<h2 class="sectiontitle">Returning Values</h2>
<p>In Perl, a function can return 0 or more scalar values as a list. This is demonstrated in the code shown in figure 96.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. say func();
8.
9. sub func {
10. return 'This is a wonderful function';
11. }</pre>
<p class="caption">Figure 96 - func.pl demonstrating the use of a function's return value</p>
<p>This is similar to previous examples, but the function does not produce any output. Instead, it returns a string. When we call the function in line 7, the return value is passed to the say statement and is then output.</p>
<p>If we want to return more than one value, we can return these values in a list as shown in figure 97.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. say foreach func();
8.
9. sub func {
10. return (1, 2, 3, 4, 5);
11. }</pre>
<p class="caption">Figure 97 - func.pl returning a list of values rather than a single value</p>
<p>Here, we have returned a list and we have used a foreach loop to output each value returned.</p>
<p>We have now seen functions that return nothing, a single scalar value or a list of scalar values. They can also return more complex things using references which we will see later.</p>
<h2 class="sectiontitle">Static Variables</h2>
<p>Perl 5.10 introduced state which allows us to create static variables. Consider the example shown in figure 98.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. func();
8.
9. sub func {
10. my $n = 10;
11. say ++$n;
12. }</pre>
<p class="caption">Figure 98 - a simple function which creates a value, increments it and then outputs the new value</p>
<p>In this simple example, the function creates a value called $n on line 10 and outputs it with the say command. Note the increment operator which increments $n. This is a pre-increment operator so the value is incremented before it is output, so the result is that 11 is output.</p>
<p>We can call this function as many times as we like as shown in figure 99.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. func();
8. func();
9. func();
10. func();
11.
12. sub func {
13. my $n = 10;
14. say ++$n;
15. }</pre>
<p class="caption">Figure 99 - the same code as shown in figure 98 but the function is being called four times rather than just once</p>
<p>The result that we see here is that each time the function is called, we get the same output of 11. This is because the value of n is discarded at the end of each function call, and reinitialized with a value of 10 for each new function call.</p>
<p>Compare this to the code shown in figure 100.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # hello.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. func();
8. func();
9. func();
10. func();
11.
12. sub func {
13. state $n = 10;
14. say ++$n;
15. }</pre>
<p class="caption">Figure 100 - the function is being called 4 times but uses a static rather than a dynamic variable</p>
<p>Note that on line 13, the variable, $n, is declared with the keyword state rather than my. We now have a static variable rather than the dynamic variable in figure 99. This means that rather than creating the variable every time the function is called, it is only created the first time so there is only one copy of the variable.</p>
<p>Each time the function is called, the value is increased so we see that in the output, we have 11, 12, 13 and 14 rather than the value 11 output four times.</p>
<p>A static variable has a value that persists between function calls, so it is sometimes known as a persistent variable.</p>
<p>Note that if you are using an earlier version of Perl than 5.16, to use state, we also need to add a pragma.</p>
<p class="inset">use feature ‘state’;</p>
<p>The word state has to be in quote marks. This is not needed if you are using a later version of Perl, but your code will still work if you include it.</p>
<p>It’s worth mentioning that other languages use the keyword static or persistent, so it is important to remember that in Perl the keyword is state.</p>
<p>This type of variable can be useful as a counter, for example, or just to keep the state of an object or value.</p>
<h2 class="sectiontitle">Predeclared Functions</h2>
<p>Figure 101 shows our func.pl code again, this is the version previously seen in figure 96.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. func();
8.
9. sub func {
10. say 'This is a wonderful function';
11. }</pre>
<p class="caption">Figure 101 - func.pl demonstrating the use of a predefined function</p>
<p>Perl has a lot if built-in functions, like any modern programming languages and we can see an example of this on line where we have called the say function. It is important to remember that say is a function and in this example, we are passing it a single argument, which is the string to be output. Note, however, that we have not used parentheses. In this case, they are optional, so we could put the argument in parentheses and it would work in exactly the same way.</p>
<p>It is more common to see this type of function without the parentheses. However, if we remove the parenetheses from the call to our own function on line 10, we will get an error because the parentheses are not optional here.</p>
<p>If we want to be able to call our function in the same way as the predefined functions, that is, without the parentheses, we need to add another use pragma</p>
<p class="inset">use subs qw ( func );</p>
<p>Now, our code would work if we omit the parentheses in the call to func and it would still work if we kept them. We can also pass a list of arguments to func using without parentheses as shown in figure 102.</p>
<pre class="inset">
1. #!/usr/bin/perl
2. # func.pl by Bill Weinman &lt;http://bw.org/contact/&gt;
3.
4. use 5.28.0;
5. use warnings;
6.
7. use subs qw ( func );
8.
9. func qw ( foo bar baz );
10.
11. sub func {
12. say foreach @_;
13. }</pre>
<p class="caption">Figure 102 - calling func without parentheses</p>
<p>The use subs pragma takes a list of strings representing the names of the functions we want to be included. In this example, we have used the qw operator, but we could have just put the function name as a string</p>
<p class="inset">use subs ( ‘func’ );</p>
<p>and that would work just as well. So we can use this to predeclare any functions we commonly use to make them just a little easier to call.</p>
</article>
<div class="btngroup">
<button class="button" onclick="window.location.href='regex.html';">
Previous Chapter - Regular Expressions
</button>
<button class="button" onclick="window.location.href='references.html';">
Next Chapter - References and Structures
</button>
<button class="button" onclick="window.location.href='perl5essentialtraining.html'">
Course Contents
</button>
<button class="button" onclick="window.location.href='/programming/programming.html'">
Programming Page
</button>
<button class="button" onclick="window.location.href='/index.html'">
Home
</button>
</div>
</body>
</html>