210 likes | 310 Views
Subroutine / Function / Method. A separate piece of code that is labeled with a name and can be called from within the main program or from other subroutines Example: sub printHelloWorldFunction { print "Hello World<br>"; } &printHelloWorldFunction();. Definition of a subroutine.
E N D
Subroutine / Function / Method A separate piece of code that is labeled with a name and can be called from within the main program or from other subroutines Example: sub printHelloWorldFunction { print "Hello World\n"; } &printHelloWorldFunction();
Definition of a subroutine Start with “sub” and then the name. Enclose the statements in curly brackets: sub Name { statements } It is good practice to group the definitions at the start or the end of the script. Use descriptive names, i.e. not “doSomething”.
Why use subroutines? To avoid duplication of code: if you are using the same lines of code twice in your program, make a subroutine. To make your script more readable: especially when a piece of code has a well defined function, consider putting it in a subroutine with an informative name. To make the code available to other programmers in the form of a Perl module, a library of Perl functions.
Subroutine 0 0 1 1 2 2 3 3 Input list output list
@output = &subroutine(@input) $output = &subroutine($input) also works: one value in and one value out
Inside the subroutine 0 0 @_ return @list 1 1 2 2 3 3 Input list output list
sub pythagoras{ my ($a, $b) = @_; my $c = sqrt($a*$a + $b*$b); return $c; } my $c = pythagoras(3,4) print $c;
Prototyping sub plus ($$) { #this subroutine is prototyped my ($term1,$term2) = @_; return $term1 + term2; } $sum = plus (2,3); print $sum; plus(1,2,3); Error message: “Too many arguments for main::plus…”
Variable scope sub plus { ($a, $b) = @_; return $a + $b; } $a = 1; $b = 2; $c = 3; print plus($b,$c), "\n"; print plus($a,$b), "\n";
Variable scope (2) • Because $a and $b are reused, the output of this script will not be what you expect. • Both lines will print 5 as the sum, because $a gets a value of 2 after the first call of the sub and $b will be 3. • This can be solve by setting the scope of $a and $b to the subroutine only, with the “my” keyword. • Now the $a in the subroutine is a different variable than the $a in the main part of the script.
Variable scope (3) sub plus { my ($a, $b) = @_; return $a + $b; } $a = 1; $b = 2; $c = 3; print plus($b,$c), "\n"; print plus($a,$b), "\n";
Arrays as arguments my @a = (2,4,6); my @b = (1,3,5); my $dot = &dotProduct(@a,@b); print "$dot\n";
@a 0 0 0 1 1 1 2 2 2 @b @_ 3 3 3
Arrays as arguments • But how can you distinguish between the two arrays in the subroutine? You can’t! • For that you need to pass a reference to the arrays instead of the arrays themselves… • To get the reference of an array, add a backslash to it: \@a • If you print the reference itself, you will see a number, a memory address.
@a 0 0 0 a 1 1 1 2 2 2 @b @_ b 3 3 3
Arrays as arguments my @a = (2,4,6); my @b = (1,3,5); my $dot = &dotProduct(\@a,\@b); print "$dot\n";
Arrays as arguments sub dotProduct { my ($a,$b) = @_; my @a = @{$a}; my @b = @{$b}; my $dot = 0; for my $i (0..$#a) { $dot += $a[$i]*$b[$i]; } return $dot; }
Exercise Create these subroutines: $GCcontent = &GCcontent($sequence); $rc = &reverseComplement($sequence); $shuffled = &shuffleSequence($sequence);