10.3. Using do
The Skipper placed a few common navigation subroutines into navigation.pm. If the Skipper merely inserts:
do 'navigation.pm'; die $@ if $@;
into his typical navigation program, it's almost the same as if the eval code were executed right at that point in the program.
That is, the do operator acts as if the code from navigation.pm were incorporated into the current program, although in its own scope block, so that lexicals (my variables) and most directives (such as use strict) from the included file don't leak into the main program.
Now the Skipper can safely update and maintain one copy of the common subroutines without having to copy and recopy all the fixes and extensions into the many separate navigation programs he creates and uses. Figure 10-1 illustrates how the Skipper can use his common library.
Figure 10-1. The Skipper uses the navigation.pm file in all his other navigation programs
Of course, this requires a bit of discipline, because breaking the expected interface of a given subroutine now breaks many programs instead of just one. The Skipper needs to give special thought to his design for reusable components and modularity design. We'll presume the Skipper has had some experience at that, but we'll show some more on that in later chapters.
By placing some of the code into a separate file, other programmers can reuse the Skipper's routines, and vice versa. If Gilligan writes a routine to drop_anchor( ) and places it in the file drop_anchor.pm, then the Skipper can use Gilligan's code by including his library:
do 'drop_anchor.pm'; die $@ if $@; ... drop_anchor( ) if at_dock( ) or in_port( );
Thus, the code that we bring in from separate files permits easy maintenance and interprogrammer cooperation.
While the code we brought in from a .pm file can have direct executable statements, it's much more common to simply define subroutines that we can load using do.
Going back to that drop_anchor.pm library for a second, what if the Skipper wrote a program that needed to "drop anchor" as well as navigate?
do 'drop_anchor.pm'; die $@ if $@; do 'navigation.pm'; die $@ if $@; ... turn_toward_heading(90); ... drop_anchor( ) if at_dock( );
That works fine and dandy. The subroutines defined in both libraries are available to this program.