Another use vs. require snafu

J

J Krugman

I've spent more hours than I care to admit trying to understand
the difference between Perl's use and require, and I discovered
today that all this effort has been a miserable waste of time,
because use and require *still* confound my attempts at coding.
For example.

I have a method "a" in package A that must invoke a class method
"b" from a package B, and the identity of package B is not known
until runtime.

package A;
#...
sub a {
my ($self, $package) = @_;
# use B;
eval { "require $package; 1" } or die "Have a cow";

$package->b;
}

In the form above, perl dies with a message "Can't locate object
method "b" via package "B" (perhaps you forgot to load "B"?)". If
I uncomment the "use B;" statement (and comment out the eval line),
the code runs fine, but of course this solution is not acceptable,
because I can't hard-code the package name.

I don't understand why perl will load B (via the eval'ed require
statement) without any errors, and still fail to find method b in
B. What gives?

TIA!

jill
 
J

Jim Keenan

J said:
I've spent more hours than I care to admit trying to understand
the difference between Perl's use and require, and I discovered
today that all this effort has been a miserable waste of time,
because use and require *still* confound my attempts at coding.
For example.

I have a method "a" in package A that must invoke a class method
"b" from a package B, and the identity of package B is not known
until runtime.

package A;
#...
sub a {
my ($self, $package) = @_;
# use B;
eval { "require $package; 1" } or die "Have a cow";

$package->b;
}

In the form above, perl dies with a message "Can't locate object
method "b" via package "B" (perhaps you forgot to load "B"?)". If
I uncomment the "use B;" statement (and comment out the eval line),
the code runs fine, but of course this solution is not acceptable,
because I can't hard-code the package name.

I don't understand why perl will load B (via the eval'ed require
statement) without any errors, and still fail to find method b in
B. What gives?

This may or may not be the problem:

"B" is part of the name of several core modules as well as a top-level
namespace on CPAN. If the code above is the code you're actually having
problems with, re-code with less problematic names.

jimk
 
B

Brian McCauley

J said:
I've spent more hours than I care to admit trying to understand
the difference between Perl's use and require,

And I just spent a long time looking at the code before I saw the mistake.
eval { "require $package; 1" } or die "Have a cow";
I don't understand why perl will load B (via the eval'ed require
statement) without any errors

It does not. Look at the shape of those brackets - what perl does
without error is simply construct the string 'require B; 1'. Remove the {}.

Note: B is the name of a standard module and therefore not one you
should use for your own modules.


, and still fail to find method b in
B. What gives?

Inspect $INC{'B.pm'} to see which B was loaded - perhaps it loaded the
standard module of that name rather than your module.
 
J

J Krugman

This may or may not be the problem:
"B" is part of the name of several core modules as well as a top-level
namespace on CPAN.

I used the names A and B for the sake of the example. The real
names of the modules are much longer.

If anyone wants to test what I described in my original post, I
give some code below. Three files, Foo.pm, Bar.pm, frobozz.pl.
Run "perl frobozz.pl". I get the same results with 5.6.1 and 5.8.4.

jill


# Foo.pm

package Foo;
use strict;

sub foo {
my $package = $_[1];
# use Bar;
# For a good time, uncomment the previous line and (optionally)
# comment out the next one.
eval { "require $package; 1" } or die "Couldn't load $package\n";

$package->bar;
}

1;

__END__

# Bar.pm

package Bar;
use strict;

sub bar {
warn "Hello from Bar::bar\n";
}

1;

__END__

# frobozz.pl

use strict;
use Foo;

Foo->foo('Bar');

__END__
 
J

J Krugman

In said:
J Krugman wrote:
And I just spent a long time looking at the code before I saw the mistake.
It does not. Look at the shape of those brackets - what perl does
without error is simply construct the string 'require B; 1'. Remove the {}.
Thanks!!!

, and still fail to find method b in
Inspect $INC{'B.pm'} to see which B was loaded - perhaps it loaded the
standard module of that name rather than your module.

Inspecting %INC is something I should have done after that bogus
eval statement and before the method call.

'nother burn, 'nother lurn.

jill
 
S

Shawn Corey

J said:
I've spent more hours than I care to admit trying to understand
the difference between Perl's use and require, and I discovered
today that all this effort has been a miserable waste of time,
because use and require *still* confound my attempts at coding.
For example.

I have a method "a" in package A that must invoke a class method
"b" from a package B, and the identity of package B is not known
until runtime.

package A;
#...
sub a {
my ($self, $package) = @_;
# use B;
eval { "require $package; 1" } or die "Have a cow";

$package->b;
}

In the form above, perl dies with a message "Can't locate object
method "b" via package "B" (perhaps you forgot to load "B"?)". If
I uncomment the "use B;" statement (and comment out the eval line),
the code runs fine, but of course this solution is not acceptable,
because I can't hard-code the package name.

I don't understand why perl will load B (via the eval'ed require
statement) without any errors, and still fail to find method b in
B. What gives?

TIA!

jill

Perl was never designed for dynamic loading of objects. (Was Perl
designed?) If you are creating object B on the fly, you will need
dynamic loading; if not, try loading all the appropriate objects and use
polymorphisms to execute the correct method.

Also see: perldoc AutoSplit

--- Shawn
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top