Getting Organised

Subroutines, modules and the wonder of CPAN

print '-' x LINE_LENGTH, "\n";

-------------------------------------------------------------

print "=" x LINE_LENGTH, "\n";

print "-o0o-" x 12, "\n";

print "- " x 30, "\n";

print ">>==<<==" x 8, "\n";

============================================================

-o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==

Named Blocks

Introducing Subroutines

Maxim 5.1

Whenever you think you will reuse some code, create a subroutine

drawline "=", REPEAT_COUNT;

drawline( "=", REPEAT_COUNT );

drawline;

drawline();

Calling Subroutines

drawline

find_a_sequence

convert_data

my_subroutine

sub1

tempsub

Naming Subroutines

sub drawline {

}

sub drawline { }

sub drawline

{

}

sub drawline

{

}

Creating Subroutines

sub drawline {

print "-" x REPEAT_COUNT, "\n";

}

The drawline Subroutine

#! /usr/bin/perl -w

# first_drawline - the first demonstration program for "drawline".

use constant REPEAT_COUNT => 60;

sub drawline {

print "-" x REPEAT_COUNT, "\n";

}

print "This is the first_drawline program.\n";

drawline;

print "Its purpose is to demonstrate the first version

of drawline.\n";

drawline;

print "Sorry, but it is not very exciting.\n";

Using drawline

This is the first_drawline program.

------------------------------------------------------------

Its purpose is to demonstrate the first version of drawline.

------------------------------------------------------------

Sorry, but it is not very exciting.

Results from first_drawline ...

print "$_[0]"; # The first parameter.

print "$_[1]"; # The second parameter.

print "$_[2]"; # The third parameter, and so on.

sub drawline {

print $_[0] x $_[1], "\n";

}

drawline;

drawline "-", REPEAT_COUNT;

drawline( "-", REPEAT_COUNT );

drawline "=", REPEAT_COUNT;

drawline( "-o0o-", 12 );

drawline "- ", 30;

drawline( ">>==<<==", 8 );

Processing parameters

#! /usr/bin/perl -w

# second_drawline - the second demonstration program for "drawline".

use constant REPEAT_COUNT => 60;

sub drawline {

print $_[0] x $_[1], "\n";

}

print "This is the second_drawline program.\n";

drawline "-", REPEAT_COUNT;

print "Its purpose is to demonstrate the second version of

drawline.\n";

Using the new drawline

drawline "-", REPEAT_COUNT;

print "Sorry, but it is still not exciting. However, it is more

useful.\n";

drawline "=", REPEAT_COUNT;

drawline "-o0o-", 12;

drawline "- ", 30;

drawline ">>==<<==", 8;

The second_drawline program, cont.

This is the second_drawline program.

------------------------------------------------------------

Its purpose is to demonstrate the second version of drawline.

------------------------------------------------------------

Sorry, but it is still not exciting. However, it is more useful.

============================================================

-o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o--o0o-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==>>==<<==

Results from second_drawline ...

Better processing of parameters

shift; # Or like this: shift();

sub drawline {

print shift() x shift(), "\n";

}

sub drawline {

$chars = shift || "-";

$count = shift || REPEAT_COUNT;

print $chars x $count, "\n";

}

drawline "=== ", 10;

drawline;

drawline "="; # Prints sixty equal signs.

drawline "*"; # Prints sixty stars.

drawline "$"; # Prints sixty dollars.

drawline 40; # Does NOT print forty dashes!

drawline 20, "-"; # Does NOT print twenty dashes!

Using the new drawline ...

#! /usr/bin/perl -w

# fourth_drawline - the fourth demonstration program for "drawline".

use constant REPEAT_COUNT => 60;

sub drawline {

$chars = shift || "-";

$count = shift || REPEAT_COUNT;

print $chars x $count, "\n";

}

The fourth_drawline program

print "This is the fourth_drawline program.\n";

drawline;

print "Its purpose is to demonstrate the fourth version of

drawline.\n";

drawline;

print "Sorry, but it is still not exciting. However, it is more

useful.\n";

drawline "=", REPEAT_COUNT;

drawline "-o0o-", 12;

drawline "- ", 30;

drawline ">>==<<==", 8;

The fourth_drawline program, cont.

drawline;

drawline( Pattern => "*" );

drawline( Count => 20 );

drawline( Count => 5, Pattern => " -oOo- " );

drawline( Pattern => "===", Count => 10 );

Even better processing of parameters

The Default Array, @_, With Assigned Values

insert array here

The %arguments Hash, With Assigned Values

insert hash here

%arguments = @_;

$chars = $arguments{ Pattern } || "-";

$count = $arguments{ Count } || REPEAT_COUNT;

sub drawline {

$chars = $arguments{ Pattern } || "-";

$count = $arguments{ Count } || REPEAT_COUNT;

print $chars x $count, "\n";

}

Processing Named Parameters

#! /usr/bin/perl -w

# fifth_drawline - the fifth demonstration program for "drawline".

use constant REPEAT_COUNT => 60;

sub drawline {

%arguments = @_;

$chars = $arguments{ Pattern } || "-";

$count = $arguments{ Count } || REPEAT_COUNT;

print $chars x $count, "\n";

}

The fifth_drawline program

print "This is the fifth_drawline program.\n";

drawline;

print "Its purpose is to demonstrate the fifth version of

drawline.\n";

drawline;

print "Things are getting a little more interesting.\n";

drawline( Pattern => "*" );

drawline( Count => 20 );

drawline( Count => 5, Pattern => " -oOo- " );

drawline( Pattern => "===", Count => 10 );

drawline;

The fifth_drawline program, cont.

This is the fifth_drawline program.

------------------------------------------------------------

Its purpose is to demonstrate the fifth version of drawline.

------------------------------------------------------------

Things are getting a little more interesting.

************************************************************

--------------------

-oOo- -oOo- -oOo- -oOo- -oOo-

==============================

------------------------------------------------------------

Results from fifth_drawline ...

+---------------+

| |

| |

| |

| |

| |

+---------------+

print "+";

drawline( Count => 15 );

print "+";

+---------------

+

A more flexible drawline subroutine

print "+";

drawline( Count => 15 );

print "+\n";

print "+", drawline( Count => 15 ), "+\n";

---------------+1+

Not Quite Right!

Returning results

sub drawline {

%arguments = @_;

$chars = $arguments{ Pattern } || "-";

$count = $arguments{ Count } || REPEAT_COUNT;

return $chars x $count;

}

#! /usr/bin/perl -w

# boxes - the box drawing demonstration program for "drawline".

use constant REPEAT_COUNT => 15;

sub drawline {

%arguments = @_;

$chars = $arguments{ Pattern } || "-";

$count = $arguments{ Count } || REPEAT_COUNT;

return $chars x $count;

}

The boxes program

print "+", drawline, "+\n";

print "|", drawline( Pattern => " " ), "|\n";

print "|", drawline( Pattern => " " ), "|\n";

print "|", drawline( Pattern => " " ), "|\n";

print "|", drawline( Pattern => " " ), "|\n";

print "|", drawline( Pattern => " " ), "|\n";

print "+", drawline, "+\n";

The boxes program, cont.

Maxim 5.2

When determining the scope of a variable, think about its visibility

#! /usr/bin/perl -w

# global_scope - the effect of "global" variables.

sub adjust_up {

$other_count = 1;

print "count at start of adjust_up: $count\n";

$count++;

print "count at end of adjust_up: $count\n";

}

$count = 10;

print "count in main: $count\n";

adjust_up;

print "count in main: $count\n";

print "other_count in main: $other_count\n";

Visibility and Scope

count in main: 10

count at start of adjust_up: 10

count at end of adjust_up: 11

count in main: 11

other_count in main: 1

Results from global_scope ...

#! /usr/bin/perl

# private_scope - the effect of "my" variables.

sub adjust_up {

my $other_count = 1;

print "count at start of adjust_up: $count\n";

$count++;

print "other_count within adjust_up: $other_count\n";

print "count at end of adjust_up: $count\n";

}

my $count = 10;

print "count in main: $count\n";

adjust_up;

print "count in main: $count\n";

print "other_count in main: $other_count\n";

Using private variables

count in main: 10

count at start of adjust_up:

other_count within adjust_up: 1

count at end of adjust_up: 1

count in main: 10

other_count in main:

Results from private_scope ...

Maxim 5.3

Unless you have a really good reason not to, always declare your variables with my

#! /usr/bin/perl

# hybrid_scope - the effect of "our" variables.

sub adjust_up {

my $other_count = 1;

print "count at start of adjust_up: $count\n";

$count++;

print "other_count within adjust_up: $other_count\n";

print "count at end of adjust_up: $count\n";

}

our $count = 10;

print "count in main: $count\n";

adjust_up;

print "count in main: $count\n";

print "other_count in main: $other_count\n";

Using global variables properly

count in main: 10

count at start of adjust_up: 10

other_count within adjust_up: 1

count at end of adjust_up: 11

count in main: 11

other_count in main:

Results from hybrid_scope ...

Maxim 5.4

If you must use a global variable, declare it with our

sub drawline {

my %arguments = @_;

my $chars = $arguments{ Pattern } || "-";

my $count = $arguments{ Count } || REPEAT_COUNT;

return $chars x $count;

}

The final version of drawline

$ man perlfunc

$ perldoc -f sleep

In-Built Subroutines

Grouping and Reusing Subroutines

Maxim 5.5

When you think you will reuse a subroutine, create a custom module

#! /usr/bin/perl -w

use lib "$ENV{'HOME'}/bbp/";

use UsefulUtils;

drawline;

Modules

package;

require Exporter;

our @ISA = qw( Exporter );

our @EXPORT = qw();

our @EXPORT_OK = qw();

our %EXPORT_TAGS = ();

our $VERSION = 0.01;

1;

Modules – Example Template

package UsefulUtils;

# UsefulUtils.pm - the useful utilities module from

# "Bioinformatics, Biocomputing and Perl".

require Exporter;

our @ISA = qw( Exporter );

our @EXPORT = qw();

our @EXPORT_OK = qw( drawline );

our %EXPORT_TAGS = ();

our $VERSION = 0.01;

use constant REPEAT_COUNT => 60;

The UsefulUtils Module

sub drawline {

# Given: a character string and a repeat count.

# Return: a string that contains the character string

# "repeat count" number of times.

#

# Notes: For maximum flexibility, this routine does NOT

# include a newline ("\n") at the end of the line.

my %arguments = @_;

my $chars = $arguments{ Pattern } || "-";

my $count = $arguments{ Count } || REPEAT_COUNT;

return $chars x $count;

}

1;

The UsefulUtils Module, cont.

$ mkdir ~/bbp/

$ cp UsefulUtils.pm ~/bbp/

Installing UsefulUtils

#! /usr/bin/perl -w

# boxes2 - the box drawing demonstration program for "drawline".

use lib "$ENV{'HOME'}/bbp/";

use UsefulUtils qw( drawline );

print "+", drawline( Count => 15 ), "+\n";

print "|", drawline( Pattern => " ", Count => 15 ), "|\n";

print "|", drawline( Pattern => " ", Count => 15 ), "|\n";

print "|", drawline( Pattern => " ", Count => 15 ), "|\n";

print "|", drawline( Pattern => " ", Count => 15 ), "|\n";

print "|", drawline( Pattern => " ", Count => 15 ), "|\n";

print "+", drawline( Count => 15 ), "+\n";

Using UsefulUtils

$ man perlmodlib

The Standard Modules

Maxim 5.6

Don't reinvent the wheel, use or extend a standard module whenever possible

http://www.cpan.org

CPAN: The Module Repository

Maxim 5.7

Don't reinvent the wheel, use or extend a CPAN module whenever possible

Maxim 5.8

When you think others might benefit from a custom module you have written, upload it to CPAN

http://search.cpan.org

Searching CPAN

$ tar zxvf ExampleModule-0.03.tar.gz

$ cd ExampleModule-0.03

$ perl Makefile.PL

$ make

$ make test

$ su

$ make install

$ <Ctrl-D>

Installing a CPAN module manually

$ man ExampleModule

$ perl -e 'use ExampleModule'

# Can't locate ExampleModule.pm in @INC.

# BEGIN failed--compilation aborted at -e line 1.

Testing the installation

$ perl -MCPAN -e "install 'ExampleModule'"

Installing a CPAN module automatically

Maxim 5.9

Always take the time to test downloaded CPAN modules for compliance to specific requirements

Where To From Here

2004-04-02T16:51:44