You are on page 1of 4

Perl Subroutines

Introduction
Perlallowstheusertodefinetheirownfunctions,calledsubroutines.Theymaybeplacedanywherein
yourprogrambutit'sprobablybesttoputthemallatthebeginningorallattheend.
Asubroutinehastheformregardlessofanyparametersthatwemaywanttopasstoit:
subNAMEBLOCK
submysubroutine
{
print"Notaveryinterestingroutine\n";
print"Thisdoesthesamethingeverytime\n";
}

Allofthefollowingwillworktocallthissubroutine.Noticethatasubroutineiscalledwithan&character
infrontofthename:
&mysubroutine;
#Callthesubroutine
&mysubroutine($_); #Callitwithaparameter
&mysubroutine(1+2,$_);
#Callitwithtwoparameters

Whenthesubroutineiscalled,parametersarepassedasalistinthespecial@_listarrayvariable.This
variablehasabsolutelynothingtodowiththe$_scalarvariable.Example:
#!/usr/bin/perlw
#subroutinebasics

######################################################
subhello_string{
return"Helloworld!\n";
}
printhello_string;
######################################################

######################################################
subprintargs{
print"@_\n";
}
&printargs("Iam","theking.");
&printargs("Youare","mysubject.");
######################################################

######################################################
subsay_hello_to{
my$name=shift;
print"Hello,$name!\n";
}
#variouswaystocalltheabovesub
say_hello_to("Ramesh");
say_hello_to"Ramesh";
&say_hello_to("Ramesh");
######################################################

######################################################

submy_sub{
print"Hello,world!\n";
}
my$ref_to_sub=\&my_sub;
$ref_to_sub>();
#printsHello,world!
######################################################

######################################################
subsoldier{
$n+=1;#globalvariable$n
print"Hello,soldiernumber$n!\n";
}
&soldier;
&soldier;
&soldier;
######################################################

Save as subbasics.pl and run.


Helloworld!
Iamtheking.
Youaremysubject.
Hello,Ramesh!
Hello,Ramesh!
Hello,Ramesh!
Hello,world!
Hello,soldiernumber1!
Hello,soldiernumber2!
Hello,soldiernumber3!

Subroutines and return value


As Perl chugs along in a subroutine, it calculates values as part of its series of actions. Whatever calculation
is last performed in a subroutine is automatically also the return value.
#!/usr/bin/perlw
subsum_of_fred_and_barney{
print"Hey,youcalledthesum_of_fred_and_barneysubroutine!\n";
$fred+$barney;#That'sthereturnvalue
}
$fred=3;
$barney=4;
$wilma=&sum_of_fred_and_barney;#wilmagets7
print"\$wilmais$wilma.\n";
$betty=3*&sum_of_fred_and_barney;#bettygets21
print"\$bettyis$betty.\n";

Save as subreturnvalue.pl and run.


Hey,youcalledthesum_of_fred_and_barneysubroutine!
$wilmais7.
Hey,youcalledthesum_of_fred_and_barneysubroutine!
$bettyis21.

That print statement is just a debugging aid, so you can see that you called the subroutine. You normally

take in those sorts of statements when youre ready to deploy your program. But suppose you added
another printto the end of the subroutine, like this (subroutineoops.pl):
subsum_of_fred_and_barney{
print"Hey,youcalledthesum_of_fred_and_barneysubroutine!\n";
$fred+$barney;#That'snotthereturnvalue
print"Hey,I'mreturningavaluenow!\n";#Oops!
}

You get:
Uselessuseofaddition(+)invoidcontextatsubreturnoops.plline5.
Hey,youcalledthesum_of_fred_and_barneysubroutine!
Hey,I'mreturningavaluenow!
$wilmais1.
Hey,youcalledthesum_of_fred_and_barneysubroutine!
Hey,I'mreturningavaluenow!
$bettyis3.

The last expression evaluated is not the addition anymore; its now the print statement, whose return
value is normally 1 , meaning printing was successful, but thats not the return value you actually
wanted. So be careful when adding additional code to a subroutine, since the last expression evaluated
will be the return value. The term void context is just a fancy way of saying that you arent using the
answer, whether that means storing it in a variable or using it any other way.
The last evaluated expression really means the last expression that Perl evaluates, rather than the last
statement in the subroutine. For example, this subroutine returns the larger value of $fredor $barney:
sublarger_of_fred_or_barney{
if($fred>$barney){
$fred;
}else{
$barney;
}
}

Adding bases: subroutine


#!/usr/bin/perlw
#subtoappendbasestoDNA
$dna='ACGTTTAGGCCTAGCCTGACGCCA';
$longerdna=addbases($dna);#$longerdnacollectsresultsofthesub
#theargument/paramenteris$dna
print"Iaddedbasesto$dnaandgot$longerdna.\n\n";
exit;
subaddbases{#addbasesisthesubcall
my($dna)=@_;#thevaluesof$dnaarepassedinto@_
$dna.='GATCCCG';#from@_thevaluesareassignedto$dna,which
#issubsvariableitdoesnthavetobethe
#thesamenameasargument,thoughinthiscase
#itis
return$dna;
}
Result (subaddbases.pl):
IaddedbasestoACGTTTAGGCCTAGCCTGACGCCAandgotACGTTTAGGCCTAGCCTGACGCCAGATCCCG.
Note that in the subroutine, the variable must be declared as my variable, otherwise code wont work.

Subroutines and command-line arguments: Counting #Gs


#!/usr/bin/perl -w
# Count #Gs in DNA on the command line
# 1, Collect DNA from arguments on command line when the user calls the
#
program
#
If no arguments are given, print a Usage statement and exit.
use strict;
unless(@ARGV) {
print "\nUsage: countGsub.pl got no command line arguments.\n";
exit;
}
# 2, Read in the DNA from the command line.
my($dna) = $ARGV[0];
# 3, Call the subroutine and collect the result.
my($no_of_Gs) = countG ($dna);
# 4, Report the result and exit.
print "\nThe DNA $dna has $no_of_Gs Gs in it!\n\n";
exit;
#############################################################
### Subroutine ###
#############################################################
sub countG {
my($dna) = @_;
my($count) = 0;
$count = ($dna =~ tr/Gg//);
return $count;
}

Save as countGsub.pl and run as follows:


1) Type (on Windows 7): perl ./countGsub.pl GGGGG (or any DNA string)
2) To see the usage statement, type: perl ./countGsub.pl and hit return key.
The code works.