0

I had exported some constants from my module. In my script I am loading my module using Mojo::Loader

my module

use constant FALSE        => 0;
use constant TRUE         => 1;

our @EXPORT = qw(FALSE TRUE);

In my script.

Mojo::Loader->new->load($my_module_name);

I was able to use my module in my script, but the constants that I exported were not accessible in my script. If I load my module with use clause. I was able to use the exported constants.

Any idea how to fix this and import the constants into my script.

Thanks!!

PMat
  • 2,039
  • 2
  • 29
  • 46

1 Answers1

1

I took a look at the code for Mojo::Loader and it turns out it cannot import stuff. It only does a require (in a string eval), but not a use. A quick grep of the source reveals that there is no import whatsoever, so you will need to call Your::Module->import yourself.

Here's a link to the relevant part of the source code and a quote:

sub load {
  my ($self, $module) = @_;

  # Check module name
  return 1 if !$module || $module !~ /^\w(?:[\w:']*\w)?$/;

  # Load
  return undef if $module->can('new') || eval "require $module; 1";

  # Exists
  return 1 if $@ =~ /^Can't locate \Q@{[class_to_path $module]}\E in \@INC/;

  # Real error
  return Mojo::Exception->new($@);
}

There is something interesting going on here. If you use foo, the import works with constants.

use foo;
print 'True: ', TRUE;

However:

require foo; 
foo->import;
print 'True: ', TRUE;

This will produce a warning Bareword "TRUE" not allowed while "strict subs" in use. So we put TRUE() to make it look less like a bareword. A constant is a sub after all. Now it will work. The same goes for doing Mojo::Loader->load('foo').

If you wrap a BEGIN block around the require and import, you can omit the parenthesis.

Thus, if you want to export constants, add parenthesis to where you call them if you want to keep using Mojo::Loader.

simbabque
  • 53,749
  • 8
  • 73
  • 136
  • I also tried to do my_module->import(); but it did not help. Still constants are not accessible – PMat Jan 15 '14 at 19:55
  • Regarding the `BEGIN` edit: I believe that has to do with what barewords Perl recognizes as subs internally at compile time, but I cannot explain it. Maybe someone else can? – simbabque Jan 15 '14 at 20:28
  • 2
    I found a reference to half an explanation pretty far down in http://perldoc.perl.org/perlmod.html#BEGIN%2c-UNITCHECK%2c-CHECK%2c-INIT-and-END saying *"Because the use statement implies a BEGIN block, the importing of semantics happens as soon as the use statement is compiled, before the rest of the file is compiled. This is how it is able to function as a pragma mechanism, and also how modules are able to declare subroutines that are then visible as list or unary operators for the rest of the current file."*. – simbabque Jan 15 '14 at 20:33