Previously we saw the problems with Perl 4 libraries. Let's now see a better solution using Perl 5 namespaces.
Other language also use namespaces. In Perl 5, in order to switch to another namespace we use the
package
keyword. (For some more clarification on what namespaces, packages, modules etc. are,
look at this article.)
We use switch to a new namespace by writing package
followed by the name of the new namespace.
Calc
in our example below. Namespaces usually start with a capital letter follower by lower-case letter,
though this is more of a convention than a hard requirement of Perl.
In this script we already have use strict;
and use warnings;
because we entered the new milleneum.
Then we have package Calc;
this means that from this point on, the code we write is in the Calc namespace
until we call package
again with some other namespace. We load use strict;
and use warnings
again, even though we don't really need them here, but we are planning to move the code of the package into another
file and there we will already want them to be part of the code. Then we add functions. (OK, in this example there
is only a single function that happens to be called add
, but don't let this minor issue confuse you. You can put
any number of functions inside the namespace.)
The we return to the main package by writing package main;
.
This is something we have not talked about yet because there was no need for it, but when you start writing a perl
script it is already inside a namespace called main
. In most of the cases we don't have to do anything with
it, but now it is handy so we can switch back to the namespace of the main script. The name itself is probably a left-over
from the C programming language where you have to declare a function called main in order to have anything running.
Note, it is called main
with lower-case letters.
So after the package main;
statement we are back in the main namespace. If we now tried to call the add
function add(3, 4)
, we would get an exception and the script would die with
Undefined subroutine &main::add called at namespaces.pl line 20..
That's because we don't have an add
function in the main namespace. Instead of that we have to write the
fully qualified name of the function, including the namespace as a prefix separated by double-colon:
Calc::add(3, 4)
namespaces.pl:
#!/usr/bin/perl
use strict;
use warnings;
package Calc;
use strict;
use warnings;
sub add {
my $total = 0;
$total += $_ for (@_);
return $total;
}
package main;
print Calc::add(3, 4), "\n";
That's how you use package
and that's how you create namespaces in Perl 5.
Comments
I don't understand what "namespace" means in Perl. I would expect names in one package to be distinct from names in another Why does Perl warn that the declaration of $debug in package main masks the declaration of $debug in package Test?
use v5.16; use strict; use warnings;
package Test; my $debug = 5; print("$debug\n");
package main; my $debug = 10; print("$debug\n");
Hi, the reason you get warning is because the variables defined using keyword my do not belong to the "symbol table" of that package. So even when you define them under differnt package, perl does not treat them as belonging to differnt namespace. Replace the my with our keyword, and now it really belongs to different namespace and perl won't complain :-)
use v5.16; use strict; use warnings;
package Test; our $debug = 5; print("$debug\n");
package main; our $debug = 10; print("$debug\n");