Bioperl Training Exercise 5
From BITS wiki
- Key in this training: CODE REUSE (which is NOT COPY PASTE)
- Before we proceed we should address the concept of name spaces and the issue of so called name space collision.
- Consider the following little script hi.pl (mind that we did not use the strict pragma, so all variables are global variables or package variables):
#!/usr/bin/perl $noise = 'Hi there !'; # or, since no arguments: # &make_noise; make_noise(); sub make_noise { print "hi.pl says: '$noise'\n"; }
- Consider yet another little script blah.pl:
#!/usr/bin/perl $noise = 'Blah, blah, blah !'; make_noise(); sub make_noise { print "blah.pl says: '$noise'\n"; } 1;
- If you run hi.pl you should see:
-
hi.pl says: 'Hi there !'
- blah.pl gives you:
-
blah.pl says: 'Blah, blah, blah !'
-
- No surprises up to here, are there ? Now, we would like to reuse the blah.pl code in the hi.pl script. The most simple way to do this, is with the require function. Before running hi.pl again, try to figure out what the output will be.
hi.pl |
---|
blah.pl says: 'Blah, blah, blah !' blah.pl says: 'Hi there !' |
- OK, this was weird, or not ? Anyway, we are witnessing 2 name space collisions here:
- the subroutine make_noise() of hi.pl is created first but is overwritten by the subroutine of blah.pl of the same name as soon as the require line is executed.
- the global variable $noise of blah.pl is overwritten by the variable of hi.pl of the same name as soon as the assignment line in hi.pl is reached.
- Now, you might ask 'What the heck is a/the name space ?'
- Consider the name space as the 'last name' of a variable. The fully qualified name of a variable is that 'last name', followed by the '::' (aka package separator) and the short name of the variable. If the last name is not explicitly provided it is main. In case of the global scalar variable $noise, the fully qualified name is $main::noise. The subroutine is a global variable as well, its fully qualified name is main::make_noise. The same can be said for the global variables in blah.pl.
- All variables have the same name and family name, hence the clash (aka name space collision).
- Resolve the name space collision by explicitly indicating the name space. This is done by using the package keyword (check perldoc).
Solution |
---|
blah.pl:
hi.pl:
Gives: blah.pl says: 'Blah, blah, blah !' hi.pl says: 'Hi there !'
|
- Next, in hi.pl, we want to explicitely call the make_noise() subroutine of blah.pl or in other words, the subroutine make_noise() of the package Blah. Also, change the subroutines in such way that the passed argument ($noise) is printed.
Solution |
---|
blah.pl:
hi.pl:
Gives: blah.pl says: 'Blah, blah, blah !' hi.pl says: 'Hi there !' blah.pl says: 'Hi there !' |
- There is also a special way to call a subroutine of another package that look more OO, namely the arrow operator (see perldoc perlop). Try out this kind of call and look carefully at the output.
Solution |
---|
hi.pl:
Gives: blah.pl says: 'Blah, blah, blah !'
hi.pl says: 'Hi there !'
blah.pl says: 'Blah' |