How to write an importer for subs in Perl?

2019-09-14 03:39发布

问题:

I have the following code:

#! /usr/bin/perl -T

{
  package MSG;
  use strict;
  use warnings;

  sub info
  {
    print STDERR join("\n", @_), "\n";
  }

  sub import
  {
    no strict 'refs';
    *{caller().'::info'} = \&info;
  }
}

{
  package main;
  use strict;
  use warnings;
  MSG->import;
#  sub info;

  info "a", "b";
}

Without the sub info; line in the main package, I get the following error:

String found where operator expected 

I think the reason is explained here. When I add the line, the code works as expected. But I do not want it in the main package.

How to move whatever sub info; does into the import function of the MSG package?

回答1:

Most people use Exporter.

BEGIN {
  package MSG;

  use strict;
  use warnings;

  use Exporter qw( import );
  our @EXPORT = qw( info );

  sub info {
    print STDERR join("\n", @_), "\n";
  }
}

{
  use strict;
  use warnings;

  BEGIN { MSG->import; }

  info "a", "b";
}

The BEGIN around import ensures the symbol is imported before info is compiled. It would be cleaner to use use, which is possible using small change.

BEGIN {
  package MSG;

  use strict;
  use warnings;

  use Exporter qw( import );
  our @EXPORT = qw( info );

  sub info {
    print STDERR join("\n", @_), "\n";
  }

  $INC{"MSG.pm"} = 1;
}

{
  use strict;
  use warnings;

  use MSG;

  info "a", "b";
}


标签: perl import