Приглашаем посетить
Бунин (bunin-lit.ru)

Section 10.6.  The Problem of Namespace Collisions

Previous
Table of Contents
Next

10.6. The Problem of Namespace Collisions

Sometimes the Skipper runs a ship into an island, but sometimes the collision involved is just a couple of names in a Perl program. Suppose that the Skipper has added all his cool and useful routines to navigation.pm and that Gilligan has incorporated the library into his own navigation package, head_toward_island:

#!/usr/bin/perl

require 'navigation.pm';

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.pm 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 Perl evaluates the require at runtime, it redefines turn_toward_port 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 we 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.pm';

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.pm file. This is great for Gilligan but awkward for the Skipper, as his file now has longer subroutine names:

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. What do we do instead?


Previous
Table of Contents
Next