Introduction
To avoid the dangerous practice of copying and pasting of code, large programs reuse chunks of code as subroutines.
”’Declaration”’
A subroutine is declared with the sub keyword. Here’s a simple subroutine definition:
sub hello {
$greeted++; # global variable
print “hi there!\n”;
}
Invoking a Subroutine
The typical way of calling that subroutine is:
hello( ); # call subroutine hello with no arguments/parameters
Another way of calling is putting Ampersand before the function name.
&hello
The term void context is just a fancy way of saying that the answer isn’t being stored in a variable or used in any other way.
Perl compiles your program before executing it, it doesn’t matter where subroutines are declared. Definitions don’t have to be in the same file as your main program. They can be pulled in from other files using the do, require, or use operators,
The last expression used in the sub routine is always the return type of a subroutine. So always be careful on it.
#!/usr/bin/perl -w use strict; my $var1 = 5; my $var2 = 6; my $sum = &add; my $mul = 7 * &add; print "the vlaue of mul is : $mul \n"; print "the value of \$sum is: $sum\n"; sub add { print "You called the add sub routine:\n"; $var1 + $var2; }
Arguments
Perl has the subroutine arguments. To pass an argument list to the subroutine , simply place the list expression, in parentheses, after the subroutine invocation. like this
* $n = &max(10,30); # This sub call has two arguments.
Perl automatically stores the parameter list (another name for the argument list) in the special array variable named @_ for the duration of the subroutine. This means that the first subroutine parameter is stored in $_[0], the second one is stored in $_[1], and so on.
There is not any relation of these variable $_[0] $_[1] etc with $_.
eg.
#!/usr/bin/perl -w use strict; sub calculate { my ($var1,$var2) = @_; my $sum = $var1 + $var2; print "the sum is: $sum\n"; } &calculate(5,6);
Excess parameter is ignored in subroutine. And insufficient parameters are also ignored you simply get undef if you go beyond the array @_.For eg. &calculate(3,4,5,6,7). only first two parameters are considered and rest are ignored. The @_ variable is private to the subroutine; @_ is always the parameter list for the current subroutine invocation.A subroutine can pass arguments to another subroutine without fear of losing its own @_ variable – the nested subroutine invocation gets its own @_ in the same way. Even if the subroutine calls itself recursively, each invocation gets a new @_.
Return Values:
All perl subroutines have a return values. There is no distinction between those that return values and those that don’t. Whatever a calculation is last performed in the subroutine its the return value.
#!/usr/bin/perl -w
sub calculate {
my ($var1,$var2) = @_;
$var1 + $var2;
}
print “The sum is:”, &calculate(5,6), “\n”;
That code will product this output:
The sum is 11
#!/usr/bin/perl -w
sub calculate {
my ($var1,$var2) = @_;
$var1 + $var2;
print “This is daya:”;
}
print “The sum is:”, &calculate(5,6), “\n”;
This will product output as:
the sum is 1. In this example the last expression evaluated is not the addition; it’s the print statement. Its return value will normally 1, meaning “Printing was successful, but thats not the return value you actually wanted. ”’Last expression evaluated will be the return value.”’
Private Variable in Subroutines
By default all variables in the Perl are global variables; that is they are accessible from the every part of the program. You can create the private variable at any time called the lexical variable with”’ my”’ operator.
sub max {
my($m, $n); # new, private variables for this block
($m, $n) = @_; # give names to the parameters
if ($m > $n) { $m } else { $n }
}
These variables are private (or scoped) to the enclosing block; any other $m or $n is totally unaffected by these two.
”’Notes on Lexical Variable”’
Those lexical variable can be used in any block, not merely in the subroutine’s block. For example they can be used in the block of an if , while or foreach.
foreach (1..10) {
my ($square) = $_ * $_;
print “$_ squared is $square. \n”;
}
The variable $square is private to the enclosing block; in this case the block of foreach loop and is not accessible outside the block.Also note that my operator doesn’t change the context of an assignment.
my($num) = @_; #List context, same as ($num) = @_;
my $num = @_; # Scalar context;, same as $num = @_;
It’s worth remembering that without the parentheses, my only declares a single lexical variable:
* my $fred, $barney; # WRONG! Fails to declare $barney
* my($fred, $barney); # declares both
Of course, you can use my to create new, private arrays as well:†
* my @phone_number;
”’The use strict Pragma”’
To tell Perl that you’re ready to be more restrictive, put the use strict pragma at the top of your program (or in any block or file where you want to enforce these rules):
* use strict; # Enforce some good programming rules
”’The return Operator”’
The return operator immediately returns a value from a subroutine:
#!/usr/bin/perl -w
use strict;
my $sum;
sub calc{
print “Enter 1st no:”;
my $i = <STDIN>;
print “Enter 2nd no:”;
my $j = <STDIN>;
return ($i+$j);
}
$sum = &calc();
print “The sum is $sum\n”;
Recursion in Perl
* program to calculate Factorial <pre>#!/usr/bin/perl -w use strict; sub fact{ my ($i) = @_; #used in list context if ($i == 0) { return(1); } else { return($i*fact($i-1)); } } my $var1; print "Enter a no. to calculate fact:"; $var1 = <STDIN>; chomp($var1); print "The factorial of $var1 is:", &fact($var1),"\n";
Omitting the Ampersand & in the function call
If the compiler sees the subroutine definition before invocation, or if Perl can tell from the syntax that it’s a subroutine call, the subroutine can be called without an ampersand, just like a built-in function.The real rule to use is this one: until you know the names of all of Perl’s built-in functions, always use the ampersand on function calls.