More controlled Module loading - Faking output from caller

S

Stumo

Hi

I'm trying to write my own function that works like use but outputs a
more user friendly error message if the module isn't present.

My current tactic is to have my function in it's own package, and it
uses File::package to do the loading - however this doesn't import
things into the correct namespace (neither does calling import()
directly for some packages that have redefined it).

Is there any way I can change what caller() returns, so my function
does not appear and everything behaves as if it was called from the
namespace that called my function?

Alternatively, are there any other solutions?

Stuart Moore
 
R

Robert 'phaylon' Sedlacek

Stumo said:
I'm trying to write my own function that works like use but outputs a
more user friendly error message if the module isn't present.

'use' is a construct that is parsed by perl as soon as it's seen. IIRC
you can't make your own 'use' functions at the moment. You'd need to
have to call your function in a BEGIN { } block. Otherwise you will run
into problems with imported symbols that aren't available at compile time.

I would propose making it a regular module with an import() method. For
example, like this syntax:

use Module::OrDieWithNiceMessage 'Module::To::Load', \@imports,
{ message => q(The module 'Module::To::Load couldn't be found) };
My current tactic is to have my function in it's own package, and it
uses File::package to do the loading - however this doesn't import
things into the correct namespace (neither does calling import()
directly for some packages that have redefined it).

Personally I prefer Class::Inspector to do such things:

use Class::Inspector;
my $module = 'Foo::Bar';
eval { require Class::Inspector->filename($module) };
if ($@) {
# handle module loading error
}
Is there any way I can change what caller() returns, so my function
does not appear and everything behaves as if it was called from the
namespace that called my function?

You could either use $module->can('import') to get at the code reference
for the original import() method and use goto to "replace" the current
subroutine with the imported one (although I don't know how you'd have
to work with @_) or use something like Sub::Uplevel (see CPAN).
Alternatively, are there any other solutions?

See the above for a few solutions. I personally never needed such a
thing, but I'm wondering if there's nothing on CPAN yet to do this kind
of stuff.

..phaylon
 
A

anno4000

Stumo said:
Hi

I'm trying to write my own function that works like use but outputs a
more user friendly error message if the module isn't present.

My current tactic is to have my function in it's own package, and it
uses File::package to do the loading - however this doesn't import
things into the correct namespace (neither does calling import()
directly for some packages that have redefined it).

Is there any way I can change what caller() returns, so my function
does not appear and everything behaves as if it was called from the
namespace that called my function?

Alternatively, are there any other solutions?

Don't call import, goto it. That preserves the calling package so
->import won't be confused. Make sure, @_ is what you need it to be,
and then (untested)

goto File::package->can( 'import') ||
die "'File::package" can't import"

Anno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,020
Latest member
GenesisGai

Latest Threads

Top