10.3. Localizing Filehandles
Very occasionally, you simply have to use a package filehandle, rather than a lexical. For example, you might have existing code that relies on hard-wired bareword filehandle names. In such cases, make sure that the symbol table entry involved is always referred to explicitly, with a leading asterisk. And, more importantly, always localize that typeglob within the smallest possible scope. For example: Applying local to the *DATA::SRC typeglob temporarily replaces that entry in the symbol table. Thereafter, the filehandle that is opened is stored in the temporary replacement typeglob, not in the original. And it's the temporary *DATA::SRC that Bozo::get_data( ) sees when it's called. Then, when the results of that call are returned, control passes back out of the body of get_fool_stats( ), at which point any localization within that scope is undone, and any pre-existing *DATA::SRC filehandle is restored. Localization prevents most of the usual problems with bareword filehandles, because it ensures that the original *DATA::SRC is unaffected by the non-lexical open inside the call to get_fool_stats( ). It also guarantees that the filehandle is automatically closed at the end of the subroutine call. And using explicitly asterisked typeglobs instead of barewords avoids any confusion if there's also a DATA::SRC( ) subroutine. Nonetheless, if you have a choice, lexical filehandles are still a better alternative. Unlike localized typeglobs, lexicals are strictly limited to the scope in which they are created. In contrast, localized package filehandles are available not only in their own scope, butas the previous example illustratesthey can also be seen in any deeper scope that is called from their own scope. So a localized package filehandle can still potentially be pre-empted (i.e., broken) by another careless open in some nested scope. |