Question

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!!

Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top