Since you are writing object-oriented perl, it is a very bad idea to import symbols from one package into another. The inheritance the Perl's standard mechanism will work fine, and all you seem to be doing here is renaming the imported methods.
The problem is that use parent doesn't call the other package's import routine, so build_gmorn is never imported into mB as gmorn.
In addition, as your error message says, gmorn is not exported by the mB module, so it cannot be imported into mFr.
If you change mB to look like this then your code will mostly work. Note that because there is no mA.pm I have had to write mA->import('gmorn') as the correct use mA 'gmorn' would fail.
package mB;
mA->import('gmorn');
use parent -norequire, 'mA';
use Sub::Exporter -setup => {
exports => {
gmorn => undef,
gnite => \&build_gnite
}
};
sub build_gnite {
my ( $class, $name, $arg ) = @_;
return sub { say "$arg->{salutation}"; }
}
Update
There is no way to get the parameters to use Sub::Exporter to "pass through" multiple levels of use, because the import subroutine needs to call the generator function. So in your example mB::import needs to call mA::build_gmorn but it has no knowledge of that subroutine so it cannot be done.
The only convenient solution is to export both the generator and a generated subroutine, so that the calling code can either use the function or export a generated function itself.
This set of programs works fine.
mA.pm
use 5.010;
use warnings;
package mA;
use Sub::Exporter -setup => {
exports => [
'build_gmorn',
gmorn => \&build_gmorn,
]
};
sub build_gmorn {
my ( $class, $name, $arg ) = @_;
return sub { say "$arg->{salutation}"; }
}
1;
mB.pm
use 5.010;
use warnings;
package mB;
use mA qw/ gmorn build_gmorn /;
use parent 'mA';
use Sub::Exporter -setup => {
exports => [
'build_gmorn',
gmorn => \&build_gmorn,
'build_gnite',
gnite => \&build_gnite
]
};
sub build_gnite {
my ( $class, $name, $arg ) = @_;
return sub { say "$arg->{salutation}"; }
}
1;
mFr.pl
use 5.010;
use warnings;
package mFr;
use parent 'mB';
mB->import(
gmorn => { salutation => 'Bon Jour' },
gnite => { salutation => 'Bon Nuit' }
);
sub new { return bless {}, shift }
my $obj = mFr->new;
$obj->gmorn();
$obj->gnite();
output
Bon Jour
Bon Nuit