[Wellington-pm] goto saves the day!

Grant McLean grant at mclean.net.nz
Thu Jul 20 19:01:00 PDT 2006


Have you ever had a bunch of related scripts or modules that all start
with ...

  use strict;
  use warnings;
  use SomeCommonModule;

and wondered if you could shorten that down?  I have.  

The problem is that 'use strict' and 'use warnings' only apply to the
scope where they are called so putting them in SomeCommonModule.pm has
no effect on whatever scope originally called 'use SomeCommonModule'.

But, if you break it down:

  use strict;

is equivalent to:

  require strict;
  strict::import();

(only with some added BEGIN style magic that we don't need to worry
about right now).

In strict.pm, there's a subroutine called 'import' that works out what
scope it was called from and adjusts stricture flags back in the
caller's scope.

So it turns out the answer is very easy, all we have to do is make
SomeCommonModule::import an alias for strict::import.  Which can be done
like this:

  package SomeCommonModule;

  *import = \&strict::import;

  1;

The same trick could be used to turn warnings on but of course 
SomeCommonModule::import can't be aliased to both strict::import and
warnings::import at the same time :-(

But we can enable warnings globally by setting $^W to 1.  So we can
combine the two techniques using goto:

  package SomeCommonModule;

  sub import {
    $^W = 1;
    goto &strict::import;
  }

  1;

In this case, goto calls strict::import after first removing
SomeCommonModule::import from the call stack.  So as far as strict.pm is
concerned, it was called directly from whatever it was that said 
'use SomeCommonModule'.

I'd never used goto in a Perl program before, so I just had to share
that.

Cheers
Grant



More information about the Wellington-pm mailing list