0

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?

Community
  • 1
  • 1
ceving
  • 21,900
  • 13
  • 104
  • 178
  • Note that this will work if you use parens: `info("a", "b");`, but like @ikegami said, most people use Exporter. – stevieb Nov 10 '15 at 16:41

1 Answers1

2

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";
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Ok the second does it. Thanks! – ceving Nov 10 '15 at 16:45
  • The Exporter does not make any difference. The `$INC{"MSG.pm"} = 1;` which makes it possible to say `use MSG` makes the difference. The first solution is simply wrong. – ceving Nov 10 '15 at 16:53