Perl sub-programs (functions)

The Perl sub-program is also a user-defined function.

A Perl sub-program is a separate piece of code that performs a special task, which reduces duplicate code and makes the program easy to read.

Perl sub-programs can appear anywhere in the program in the following syntax format:

sub subroutine{
   statements;
}

Call the sub-program syntax format:

subroutine( 参数列表 );

The sub-program methods are called in the following version of Perl 5.0 as follows:

&subroutine( 参数列表 );

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

Let's look at a simple example:

#!/usr/bin/perl

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

# 函数调用
Hello();

The above procedure is performed and the output is:

Hello, World!

Pass parameters to sub-programs

Perl subprograms can accept multiple parameters just like other programming, and subprogramme parameters are indicated by a special array.

So the first argument of the sub-program is $[0,' the second argument is $_1, and so on.

Whether the parameters are of a standard or array type, perl calls them by reference by default when the user passes them to a sub-program.

#!/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);

The above procedure is performed and the output is:

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

The user can change the value of the corresponding actual parameter by changing the value in the array.

Pass a list to the sub-program

Because the variable is an array, it can pass a list to a sub-program.

But if we need to pass in the calibration and array parameters, we need to put the list on the last parameter, as follows:

#!/usr/bin/perl

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

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

The above program combines the calibration and the number, and the output is:

列表为 : 10 1 2 3 4

We can pass in multiple arrays and hashes to subroutes, but when multiple arrays and hashes are passed in, we can result in the loss of independent identities. So we need to use references (as described in the next section) to pass.

Pass a hash to the child program

When a hash table is passed to a subroute, it is copied to . . . and the hash table is 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' => 'youj', 'age' => 3);

# 传递哈希
PrintHash(%hash);

The output of the above program execution is:

age : 3
name : youj

The child program returns a value

Subprograms can return function values using the return statement, just like other programming languages.

If the return statement is not used, the last line statement of the subsys program is the return value.

#!/usr/bin/perl

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

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

The output of the above program execution is:

3

In subrougers we can return punctuation, arrays, and hashes, but when multiple arrays and hashes are returned, it results in the loss of a separate identity. So we need to use references (as described in the next section) to return multiple arrays and functions.


The private variable of the sub-program

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

If we need to set a private variable, we can use the my operator to set it.

The my operator is used to create a synth scope variable, a variable created by my that survives where the declaration begins until the end of the closed-cooperative domain.

A closed-cooperative domain can refer to an area in a pair of parentheses, between a file, or an if, while, foreach, eval string.

The following example shows 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, W3Cschool!";
   print "函数内字符串:$string\n";
}
# 调用函数
PrintHello();
print "函数外字符串:$string\n";

The output of the above program execution is:

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

The temporary assignment of the variable

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

The variable defined by local does not exist in the main program, but in the sub-program called by the sub-program and the sub-program called by the sub-program. You can assign them values when defining, such as:

#!/usr/bin/perl

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

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

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

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

The output of the above program execution is:

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

Static variables

The state operator function is similar to the static modifier in C, and the state keyword makes local variables persistent.

State is also a synth variable, so it works only in the scope of the word that defines the variable, for example:

#!/usr/bin/perl

use feature 'state';

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

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

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

The output of the above program execution is:

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

Note 1: State can only create variables within a closed cooperative domain that are within a sub-program.

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

Note 3: State can declare the calibration, array, hash. H owever, arrays and hashes cannot be initialized when they are declared (at least Perl 5.14 does not support them).


The sub-program calls the context

During a sub-program call, different types of values are returned based on the context, such as the following localtime() sub-programs, strings are returned in the standard context, and lists are returned in the 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 output of the above program execution is:

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