Chapter 4 in Learning Perl.
We have been using a form of subroutines all along. Perl functions are basically built in subroutines. You call them (or "invoke") a function by typing its name, and giving it one or more arguments.
Example: Length
my $seq = 'ATGCAAATGCCA';
my $seq_length = length $seq; ## OR
my $seq_length = length($seq);
# $seq_length now contains 12
|
Perl gives you the opportunity to define your own functions, called "subroutines". In the simplest sense, subroutines are named blocks of code that can be reused as many times as you wish.
Example: A very basic subroutine
sub Hello {
print "Hello World!!\n";
}
print "Sometimes I just want to shout ";
Hello(); #or &Hello;
|
Example: Some simple subroutines
sub hypotenuse {
my ($a,$b) = @_;
return sqrt($a**2 + $b**2);
}
sub E {
return 2.71828182845905;
}
#########
$y = 3;
$x = hypotenuse($y,4);
# $x now contains 5
$x = hypotenuse((3*$y),12);
# $x now contains 15
$value_e = E();
# $value_e now contains 2.71828182845905
|
This way of using subroutines makes them look suspiciously like functions. Note: Unlike a function, you must use parentheses when calling a subroutine in this manner, even if you are giving it no arguments.
Perhaps the most important concept to understand is that values are passed to the subroutine in the default array @_. This array springs magically into existence, and contains the list of values that you gave to subroutine (within the parentheses).
Example: The magic of @_
sub Add_two_numbers {
my ($number1) = shift; # get first argument from @_ and put it in $number1
my ($number2) = shift; # get second argument from @_ and put it in $number2
my $sum = $number1 + $number2;
return $sum;
}
sub Add_two_numbers_2 {
my ($number1,$number2) = @_;
my $sum = $number1 + $number2;
return $sum;
}
sub Add_two_numbers_arcane {
return ($_[0] + $_[1]);
}
|
Example: A more complex subroutine with different returns
sub Number_Examiner {
my $number = shift;
unless ($number =~ /^\d+$/){
return "You sure this is a number?";
}
if ($number >= 100){
return "Big Number!";
}
elsif ($number > 50){
return "Bigger than 50!;
}
else {
return "Wee Little Number";
}
}
|
Example: Know what you expect
my ($value1,$value2,$value3) = ReturnThreeValues();
# if you are expecting three values back, make space for them.
my (@values) = ReturnThreeValues(); # another way to do it
my ($value1,$value2) = ReturnThreeValues();
# the last value is lost, gone, vanished, DOA... You may have
wanted to do this.
|
Variables that you use in a subroutine should be made private to that
subroutine with the my operator. This avoids accidentally overwriting
similarly-named variables in the main program. If you already included use
strict at the top of your program, perl will check that all variables are
introduced with my.
Why Use My?
my $var = "Boo!";
Scary();
print "$var\n";
sub Scary{
print "$var\n";
$var = "Eeek!";
}
# The results:
Boo!
Eeek!
|
Variables made private with my only exist within a block (curly braces). The subroutine body is a block, so the my variables only exist within the body of the subroutine.
You can make scalars, arrays and hashes private. If you apply my() to a list, it makes each member of the list private.
{ # start a block
my $scalar; # $scalar is private
my @array; # now @array is private
my %hash; # %hash is private
# same thing, but in one swell foop
my ($scalar,@array,%hash);
} |