- Perl ›
- here
How to create a subroutine
Learn how to create a subroutine. A subroutine is a function that allows you to name and call a set of functions. It is the same as a function called a function in other languages. Perl builtin functions are explained in Perl builtin functions.
Subroutine definition
To define a subroutine:
sub Subroutine name { # process }
As a simple subroutine, let's define a subroutine named total that finds the sum of two values.
sub total { # (1) Receiving arguments my ($num1, $num2) = @_; # (2) Processing my $total = $num1 + $num2; # (3) Return value return $total; }
(1) The argument is stored in the variable " @_ ". I've reassigned the variable $num1 and $num2 to give the arguments descriptive names. (2) The two values are totaled. (3) The return value can be returned using return function.
Subroutine call
To call the subroutine: You can pass an argument and receive the processed result as a return value.
Return value = Subroutine (argument);
Now let's call the total function we created earlier.
use strict; use warnings; # (1) Value to be passed as an argument my $num1 = 1; my $num2 = 2; # (2) Subroutine call my $total = total ($num1, $num2); # (3) Subroutine definition sub total { my ($num1, $num2) = @_; my $total = $num1 + $num2; return $total; }
(1) This is the value to be passed to the argument. (2) This is a subroutine call. The return value is assigned to $total. The result of adding 1 and 2 is returned, so $total is 3. (3) Subroutine definitions can also be placed under the call. This is because the subroutine definition is read at compile time.
Subroutine arguments
Explains how to receive subroutine arguments.
Receive one argument
A common way to receive a single argument is to use the shift function.
sub func { my $arg = shift; }
When you call the shift function in a subroutine, "@_" is the implicit argument of the shift function. So the above is
sub func { my $arg = shift @_; }
Will be the same as.
Receive multiple arguments
A commonly used method when receiving multiple arguments is list assignment.
sub func { my ($arg1, $arg2) = @_; }
The first element of @_ is assigned to $arg1 and the second element is assigned to $arg2.
If the arguments are of the same type, they should be received in an array.
sub func { my @args = @_; }
Access arguments directly
"@_" Is an array, but you can also access this array directly.
# First argument $_[0] # Second argument $_[1]
This style of writing reduces readability and is recommended not to be used unless performance is absolutely necessary.
Pass an array as a subroutine argument
You can pass an array to a subroutine.
# Passing side my $num_total = sum (@nums); # Recipient sub sum { my @nums = @_; # process }
Pass a hash as a subroutine argument
You can also pass a hash to the subroutine. On the receiving side, @_ will be assigned to the hash. In Perl, the contents of an array are lists, so you can assign them to hashes.
# Passing side my $examin_total = sum_examin (%examin); # Recipient sub sum_examin { my %examin = @_; # process }
I want to pass multiple arrays to a subroutine
If you want to pass multiple arrays to a subroutine, you need to pass them as an array reference.
my @array1; my @array2; func (\@array1, \@array2); sub func { my ($array1, $array2) = @_; }
If you pass two arrays as shown below, it will become one array and it will not work.
my @array1; my @array2; func (@array1, @array2); sub func { # It becomes one array my @array = @_; }
Pass arrays and hashes separately to subroutine
What if I want to put both an array and a hash in a subroutine? In such cases, you need to use array reference and hash reference.
# Passing side my $max_num = summary ([1, 2, 3], {how =>'max'}); # Recipient sub summary { my ($nums, $option) = @_; # process }
Allow both "hash" and "hash reference" to be received as subroutine arguments
To receive a hash or hash reference in a subroutine, write:
func (name =>'Ken', age => 19); func ({name =>'Ken', age => 19}); sub func { # Convert to hash reference as needed my $arg = ref $_[0] eq 'HASH' ? $_[0] : {@_}; }
If the argument is a hash reference, it is assigned as it is, and if it is a hash, it is converted to a hash reference. $_[0] is the first element of the argument @_.
Typical pattern of how to receive arguments
Here is a typical pattern of how to receive arguments.
(1) Multiple scalars
search ('aiueo', 'eo', 2); sub search { my ($str, $search, $offset) = @_; }
Receive in a list and assign each value in the list to a scalar on the receiving side.
(2) Simple list
average (1,2,3,4,5); sub average { my @nums = @_; }
Receive it in a list and assign it to an array.
(3) One scalar and list
search_file ('file', 'apple', 'dog'); sub search_file { my ($file, @search_list) = @_; }
The first argument is assigned to the scalar, and the second and subsequent arguments are assigned to the array.
(4) Simple hash
search_arg_hash (str =>'aiueo', search =>'eo', offset => 2); sub search_arg_hash { my %arg = @_; my ($str, $search, $offset) = @arg {'str', 'search', 'offset'}; }
Substitute in the hash on the receiving side. If the number of arguments increases, it is a nice interface to give the arguments a name using a hash.
It is not always necessary to reassign the hash to the scalar, but it is often easier to see and code.
(5) One scalar and hash
parse_file ('in_file', out_file =>'out_file', search_path =>'dir'); sub parse_file { my ($in_file,%opt) = @_; my ($out_file, $search_path) = @opt {'out_file', 'search_path'}; return; }
Assign the first argument to the scalar and the second and subsequent arguments to the hash. You can use this interface if the first argument is a required argument and the other arguments are considered optional.
Subroutine return value
Return the scalar value as the return value
Basically, the scalar value is returned as the return value of the subroutine.
sub func { my $name = 'Ken'; return $name; }
Return an array or hash as a return value
Perl can also return lists (arrays and hashes).
func { my @nums = (1, 2, 3); return @nums; }
However, this method is not recommended.The recommended method is to return the "array reference" and "hash reference" described below.
You can also use wantarray function to return arguments depending on the context of the caller, but this is not recommended. The reason is that changing the return value depending on the context forces the user to write "scalar func ()" at some point to enforce the scalar context.
Return reference as return value
Array reference and hash reference are also scalar values, so they can be returned as return values.
# Returns an array reference as a return value sub func { my $nums = [1, 2, 3]; return $nums; } # Returns a hash reference as a return value sub func { my $score = {math => 100, english => 90}; return $score; }
Single return
A single return returns an undefined value undef in a scalar context and an empty list () in a list context.
sub func_name { # process ... return; }
It is customary to use a "single return" if you want to return an undefined value. "Return undef" has some advantages, but it seems to be used less frequently.
Setting default values
You may want to specify a default value for the subroutine argument. In such a case, if the argument is undefined, set the default value.
sub num { my $num = shift; unless (defined $num) { $num = 0; } }
Since Perl 5.10 introduced a convenient "defined-or operator", you can also write: If the left side is undefined, the value on the right side will be assigned.
sub num { my $num = shift; $num //= 0; }
Error handling
Explains how to handle errors in subroutine.
How to return undef
The easiest way is to return "undef" when the subroutine fails. Returns undef with a single return.
sub foo { my $error; # ... if ($error) return; } }
The caller checks the return value.
my $ret = foo (); unless (defined $ret) { # Error handling }
How to throw an exception
The recommended method is to throw an exception when an error occurs. Use the die function to throw an exception.
sub foo { my $error; # ... if ($error) die "Error"; } }
If you want to throw an exception in a module, use the carp module's croak function. The caller information is easy to understand.
use Carp 'croak'; sub foo { my $error; # ... if ($error) croak "Error"; } }
The caller catches the exception as follows: You can catch exceptions by using eval. Note that we need a semicolon at the end of the eval block.
eval { foo (); }; if (my $error = $@) { # Error handling }
When an exception occurs, the content of the error is stored in predefined variable called "$@". Since "$@" may be overwritten by a global variable, it is recommended to assign it to a lexical variable immediately.
For a detailed explanation of exception handling, see "Perl's" Exception Handling "Mechanism-Error Notification and Detection".
Subroutine exercises
I have created an exercise to understand the subroutine properly.
Learning themes
CSV, array of arrays, array of hashes, maximum and minimum values, sort, bubble sort, ascending, descending order
Subroutine reference
This is a description of the subroutine reference.
Learning themes
Subroutine reference, polymorphism, dispatch tables, signal handlers, event-driven programming
Subroutine technique
Function parenthesis omission rules
You may or may not use builtin functions parentheses.
# With parentheses print('Hello'); # Without parentheses print'Hello';
You may or may not use parentheses for functions imported from the module.
# Functions imported from module use Carp 'croak'; croak'Error';
Parentheses are required if the function definition is after the position where the function is used.
# Parentheses are required if the function definition is at the end func (); sub func { ... }
There is no such criterion as to whether to omit the parentheses. Decide on "whether it is easy for others to read" and "beauty".
* Regarding the relationship with the prototype, I will not write it because the prototype is deprecated.
Redefine subroutine (monkey patch)
Perl allows you to redefine a subroutine definition once it has been done.
sub sum {...} no warnings'redefine'; sub sum {...}
If you redefine a subroutine, you will be warned of the redefinition. You can remove the warnings by writing no warnings'redefine'; to remove this.
Overwriting a subroutine is sometimes referred to as a monkey patch. If you find a subroutine that has a bug, you can temporarily overwrite the subroutine and apply a patch.
caller function - get the name of the function you are executing
Use the caller function to get the name of the function you are executing. For the caller function, see "caller function - get the name of the function being executed".
Get the arguments of the calling subroutine
You can use the caller function to get the package name, subroutine name, etc. of the caller of the function. It is also possible to get the arguments of the calling subroutine.
To get the arguments of the calling function, call the caller function in the DB namespace in the list context. @DB::args is set to the argument of the calling function. DB is a module used for debugging. Since the namespace will be temporarily changed to DB, let's enclose it in a block. When the block is finished, it will return to the original namespace.
sub a2 { { # Change to DB package package DB; # When you call the caller function in list context my @c = caller 1; # Arguments are stored in @DB::args my @args = @DB::args; } }
Subroutine autoloading
Perl has a feature called autoloading that defines a function that will be executed if a subroutine isn't defined.
Dynamic creation of subroutine
You can dynamically create subroutine in Perl.
Creating a closure
For information on creating "closures" in Perl, see How to create "closures" in Perl.
Reading material about subroutine
- Subroutine definitions are not affected by scope
- Compare the flexibility of Perl subroutine with C
- Keep in mind to create good subroutine
- Subroutine exercises
List of Perl builtin functions
If you want to see a list of Perl builtin functions, see List of Perl functions.