2.6 The Problem of Namespace Collisions
Suppose that the Skipper has
added all his cool and useful routines to
navigation.pl and that Gilligan has incorporated
the library into his own navigation package
head_towards_island:
#!/usr/bin/perl
require 'navigation.pl';
sub turn_toward_port {
turn_toward_heading(compute_heading_to_island( ));
}
sub compute_heading_to_island {
.. code here ..
}
.. more program here ..
Gilligan then has his program debugged (perhaps with the aid of a
smart person whom we'll call "the
Professor"), and everything works well.
However, now the Skipper decides to modify his
navigation.pl library, adding a routine called
turn_toward_port that makes a 45-degree turn
toward the left (known as "port" in
nautical jargon).
Gilligan's program will fail in a catastrophic way,
as soon as he tries to head to port: he'll start
steering the ship in circles! The problem is that the Perl compiler
first compiles turn_toward_port from
Gilligan's main program, then when the
require is evaluated at runtime, the definition
for turn_toward_port is redefined as the
Skipper's definition. Sure, if Gilligan has warnings
enabled, he'll notice something is wrong, but why
should he have to count on that?
The problem is that Gilligan defined
turn_toward_port as meaning "turn
toward the port on the island," while the Skipper
defined it as "turn toward the
left." How do you resolve this?
One way
is to require that the Skipper put an explicit prefix in front of
every name defined in the library, say
navigation_. Thus, Gilligan's
program ends up looking like:
#!/usr/bin/perl
require 'navigation.pl';
sub turn_toward_port {
navigation_turn_toward_heading(compute_heading_to_island( ));
}
sub compute_heading_to_island {
.. code here ..
}
.. more program here ..
Clearly, the navigation_turn_toward_heading comes
from the navigation.pl file. This is great for
Gilligan, but awkward for the Skipper, as his file now becomes:
sub navigation_turn_toward_heading {
.. code here ..
}
sub navigation_turn_toward_port {
.. code here ..
}
1;
Yes, every scalar, array, hash, filehandle, or subroutine now has to
have a navigation_ prefix in front of it to
guarantee that the names won't collide with any
potential users of the library. Obviously, for that old sailor, this
ain't gonna float his boat. So, what do you do
instead?
|