in reply to Re: Export and use different package in module
in thread Export and use different package in module

I'll try to post it, see if it makes more sense.

main

use strict; use warnings; use File::Basename qw(dirname); use Cwd qw(abs_path); use lib dirname(dirname abs_path $0); use Library; print STDOUT $hash{"key"} . "\n"; exit 0;

this works

Library.pm

package Library; use strict; use warnings; use Exporter qw(import); our @EXPORT = qw( %hash ); our %hash = ( "key" => "Hello world!" ); 1;

these don't work

Library2.pm

package Library2; use strict; use warnings; our @EXPORT = qw( return_string ); sub return_string { return "Hello embedded library"; }

Library.pm

package Library; use strict; use warnings; use Exporter qw(import); our @EXPORT = qw( %hash ); use File::Basename qw(dirname); use Cwd qw(abs_path); use lib dirname(dirname abs_path $0); use Library2; package Library2; our %hash = ( "key" => return_string() ); 1;

I can understand it looks like the namespaces are overlapping, but the definition isn't exported even with 'our'. Just fiddled around with it, I can do our %hash = (); BEFORE the package othernamespace, and export the modification. That'll work for my case, but I'd rather not have 3-4 places I need to put the hash instead of just export and our. It seems my gripe is that a variable declared before the package othernamespace trickles down, but a variable declared after the package othernamespace doesn't trickle up when it's the same file, even though there's no complaint about the definition in another namespace and not in the original.

Replies are listed 'Best First'.
Re^3: Export and use different package in module
by haukex (Archbishop) on Feb 22, 2019 at 20:38 UTC

    First, note that Library2.pm is missing the use Exporter qw(import);, so nothing is actually exported when you do use Library2;.

    I suspect you added the package Library2; to Library.pm to work around that? However, the effect of doing so is that our %hash is declared in the current package, which is now Library2, so you're assigning a value to %Library2::hash, while what Library.pm is exporting is %Library::hash. Although you could change our %hash = ... into %Library::hash = ..., that's just fixing a workaround with a workaround, and the IMO much cleaner solution is to add the use Exporter qw(import); statement I mentioned above to Library2.pm, and just remove the package Library2; from Library.pm, which is then no longer needed, because now sub return_string will be exported from Library2 into Library and be callable there.

    BTW, this:

    use File::Basename qw(dirname); use Cwd qw(abs_path); use lib dirname(dirname abs_path $0);

    Can be replaced by the more reliable:

    use FindBin; use lib $FindBin::Bin;

      Library2 is outside of my control (not inherently), but I shouldn't have to modify the library if I'm not expecting to export stuff from IT, only make writing functions using the namespace easier. The library is actually Device::BCM2835, and since using functions in it also should be using values from it, I get things like

      #inside a function Device::BCM2835::gpio_fsel ( Device::BCM2835::RPI_V2_GPIO_P1_12, Devic +e::BCM2835::BCM2835_GPIO_FSEL_ALT5 );

      instead of

      package Device::BCM2835; #some place later in a function gpio_fsel(RPI_V2_GPIO_P1_12, BCM2835_GPIO_FSEL_ALT5);

      I found the our definition and then modification works with the hash, but it doesn't work with a sub even though I declare the sub the same way! If I try our sub, it's experimental.

        Device::BCM2835 does export RPI_V2_GPIO_P1_12 and BCM2835_GPIO_FSEL_ALT5, so you should be able to say

        use Device::BCM2835 qw/RPI_V2_GPIO_P1_12 BCM2835_GPIO_FSEL_ALT5/;

        to get those into your namespace. As for gpio_fsel, which apparently isn't exported for some reason, you could use this workaround:

        *gpio_fsel = \&Device::BCM2835::gpio_fsel;

        For more than one function:

        for my $s (qw/ gpio_fsel gpio_set /) { no strict 'refs'; *$s = \&{"Device::BCM2835::$s"}; }

        To understand what's going on in the above, I recommend perlmod.