Perl subroutines (functions)


Perl subprograms are also user-defined functions.

Perl subroutine is a separated piece of code that performs a special task. It can reduce repeated code and make the program easier to read.

Perl subprograms can appear anywhere in the program. The syntax format is as follows:

sub subroutine{
   statements;
}

The syntax format for calling a subprogram:

subroutine( 参数列表 );

Call the subprogram method in Perl 5.0 or below As follows:

&subroutine( 参数列表 );

In the new version, although this calling method is also supported, it is not recommended.

Next let’s look at a simple example:

#!/usr/bin/perl

# 函数定义
sub Hello{
   print "Hello, World!\n";
}

# 函数调用
Hello();

Execute the above program, the output result is:

Hello, World!

Pass parameters to the subroutine

Perl subprograms can accept multiple parameters like other programming, and the subprogram parameters are marked with the special array @_.

So the first parameter of the subroutine is $_[0], the second parameter is $_[1], and so on.

Regardless of whether the parameters are scalar or array, when the user passes the parameters to the subroutine, Perl calls them by reference by default.

#!/usr/bin/perl

# 定义求平均值函数
sub Average{
   # 获取所有传入的参数
   $n = scalar(@_);
   $sum = 0;

   foreach $item (@_){
      $sum += $item;
   }
   $average = $sum / $n;
   print '传入的参数为 : ',"@_\n";           # 打印整个数组
   print "第一个参数值为 : $_[0]\n";         # 打印第一个参数
   print "传入参数的平均值为 : $average\n";  # 打印平均值
}

# 调用函数
Average(10, 20, 30);

Execute the above program, the output result is:

传入的参数为 : 10 20 30
第一个参数值为 : 10
传入参数的平均值为 : 20

Users can change the value of the corresponding actual parameter by changing the value in the @_ array.

Passing a list to a subroutine

Since the @_ variable is an array, it can pass a list to the subroutine.

But if we need to pass in scalar and array parameters, we need to put the list on the last parameter, as shown below:

#!/usr/bin/perl

# 定义函数
sub PrintList{
   my @list = @_;
   print "列表为 : @list\n";
}
$a = 10;
@b = (1, 2, 3, 4);

# 列表参数
PrintList($a, @b);

The above program combines scalars and arrays, and outputs the result For:

列表为 : 10 1 2 3 4

We can pass multiple arrays and hashes to the subroutine, but when passing in multiple arrays and hashes, independent identities will be lost. So we need to use references (will be introduced in the next chapter) to pass.

Passing a hash to a subroutine

When a hash table is passed to a subroutine, it will be copied into @_ and the hash table will be expanded into a list of key/value combinations.

#!/usr/bin/perl

# 方法定义
sub PrintHash{
   my (%hash) = @_;

   foreach my $key ( keys %hash ){
      my $value = $hash{$key};
      print "$key : $value\n";
   }
}
%hash = ('name' => 'php', 'age' => 3);

# 传递哈希
PrintHash(%hash);

The execution output of the above program is:

age : 3
name : php

Subprogram return value

Subprograms can use the return statement to return function values ​​like other programming languages.

If the return statement is not used, the last line of the subprogram will be used as the return value.

#!/usr/bin/perl

# 方法定义
sub add_a_b{
   # 不使用 return
   $_[0]+$_[1];  

   # 使用 return
   # return $_[0]+$_[1];  
}
print add_a_b(1, 2)

The execution output of the above program is:

3

In the subroutine, we can return scalars, arrays and hashes, but when returning multiple arrays and hashes, independent values ​​will be lost. logo. So we need to use references (will be introduced in the next chapter) to return multiple arrays and functions.


Private variables of subprograms

By default, all variables in Perl are global variables, which means that variables can be called anywhere in the program.

If we need to set private variables, we can use the my operator to set them. The

my operator is used to create lexically scoped variables. Variables created by my survive from the beginning of the declaration until the end of the closed scope.

The closed scope refers to the area within a pair of curly braces, a file, or an if, while, for, foreach, eval string.

The following example demonstrates how to declare one or more private variables:

sub somefunc {
   my $variable; # $variable 在方法 somefunc() 外不可见
   my ($another, @an_array, %a_hash); #  同时声明多个变量
}
#!/usr/bin/perl

# 全局变量
$string = "Hello, World!";

# 函数定义
sub PrintHello{
   # PrintHello 函数的私有变量
   my $string;
   $string = "Hello, php!";
   print "函数内字符串:$string\n";
}
# 调用函数
PrintHello();
print "函数外字符串:$string\n";

The execution output of the above program is:

函数内字符串:Hello, php!
函数外字符串:Hello, World!

Temporary assignment of variables

We can use local to provide temporary values ​​for global variables and return the original values ​​after exiting the scope.

local The variable defined does not exist in the main program, but exists in the subprogram and the subprograms called by the subprogram. You can assign a value to it when defining, such as:

#!/usr/bin/perl

# 全局变量
$string = "Hello, World!";

sub Printphp{
   # PrintHello 函数私有变量
   local $string;
   $string = "Hello, php!";
   # 子程序调用的子程序
   PrintMe();
   print "Printphp 函数内字符串值:$string\n";
}
sub PrintMe{
   print "PrintMe 函数内字符串值:$string\n";
}

sub PrintHello{
   print "PrintHello 函数内字符串值:$string\n";
}

# 函数调用
Printphp();
PrintHello();
print "函数外部字符串值:$string\n";

The above program execution output result is:

PrintMe 函数内字符串值:Hello, php!
Printphp 函数内字符串值:Hello, php!
PrintHello 函数内字符串值:Hello, World!
函数外部字符串值:Hello, World!

Static variable

The function of the state operator is similar to that in C The static modifier and the state keyword make local variables persistent.

state is also a lexical variable, so it is only valid in the lexical scope in which the variable is defined. For example:

#!/usr/bin/perl

use feature 'state';

sub PrintCount{
   state $count = 0; # 初始化变量

   print "counter 值为:$count\n";
   $count++;
}

for (1..5){
   PrintCount();
}

The output result of the execution of the above program is:

counter 值为:0
counter 值为:1
counter 值为:2
counter 值为:3
counter 值为:4

Note 1: state can only create variables whose closed scope is within the subroutine.

Note 2: state was introduced from Perl 5.9.4, so use must be added before use.

Note 3: state can declare scalars, arrays, and hashes. But arrays and hashes cannot be initialized when they are declared (at least not in Perl 5.14).


Subprogram calling context

During the subprogram calling process, different types of values ​​will be returned according to the context. For example, the following localtime() subprogram returns a scalar context String, return list in list context:

#!/usr/bin/perl

# 标量上下文
my $datestring = localtime( time );
print $datestring;

print "\n";

# 列表上下文
($sec,$min,$hour,$mday,$mon, $year,$wday,$yday,$isdst) = localtime(time);
printf("%d-%d-%d %d:%d:%d",$year+1990,$mon+1,$mday,$hour,$min,$sec);

print "\n";

The above program execution output result is:

Sun Jun 12 15:58:09 2016
2106-6-12 15:58:9