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

It's really backwards having to turn off warnings to just add something to the current namespace without having to turn off warnings and hack around it

Nowhere in this thread are warnings turned off, so I'm not sure what you mean. If you mean strict, then yes, turning off strict 'refs' is necessary when doing this kind of exporting/importing with strict enabled. More specifically, it's required because the second method I showed uses Symbolic references to build the names of the symbols from strings. Exporter does it internally too.

Can I change a sub declaration to force it to assign the sub to the same sub in the current namespace like the hash? Using the experimental 'lexical_subs' works for what I expect.

The code I showed copies a reference to a sub from one symbol table to another, which is how importing/exporting works in Perl. As I said, have a look at perlmod, or perhaps my post here (the paragraph beginning with "Once you understand...", the first two bullet points, and the "Update").

Other than that I'm not sure I understand your expectations, especially in reference to Lexical Subroutines. Maybe you could show with code what you are expecting to be able to do?

considering that variables are exported in a sensible way, but the functions aren't,

Yes, I think it's a limitation in Device::BCM2835 that it does not export its functions, and IMO one that might be worth a request to the module's author to see if they might add that. But as long as they don't, and you don't want to patch the module either (as you said), you'll have to work around it, for example with the code I showed.

warnings/strict are useless

Sorry, I don't understand this point. If you mean the no strict 'refs';, then its effect is limited to its lexical scope, which is why I put it inside the loop, so that it does not affect the rest of the program.

Replies are listed 'Best First'.
Re^8: Export and use different package in module
by chenhonkhonk (Acolyte) on Feb 23, 2019 at 06:10 UTC

    A hash is exported normally using our %hash = (); and adding to it works after doing package <something>;. Functions aren't, and I have to use experimental our sub to do it, which doesn't make sense (since both hashes and functions would expected to be managed in the namespace the same way). When it came to strict/warnings, they offered no information on resolving the issue, which as far as the language is currently concerned, only variables can be handled.

      Ohh, I think I see what you are getting at - is it the following?

      package Foo; our $var = "Hello"; sub func { print $var, "\n" } package Bar; print $var, "\n"; # Prints "Hello" func(); # Error: Undefined subroutine &Bar::func called

      In this example, why is $var still accessible when we've switched to package Bar, while sub func is no longer accessible? Well, the answer is in what our actually does: it "makes a lexical alias to a package (i.e. global) variable of the same name in the current package for use within the current lexical scope." Because in the above example, package Bar is in the same lexical scope as package Foo, anything declared for the current lexical scope in package Foo is still accessible in package Bar. The package variable is $Foo::var, but its alias $var is available in the whole lexical scope.

      sub declarations don't work the same way that our does - in the above example, sub func sets up &Foo::func, but that does not carry over into Bar. I understand this distinction may be a bit strange, but it also has historical reasons: our wasn't added to the language until Perl 5.6, about six years after Perl 5.0 - before that, there was the vars pragma. (BTW, note that Lexical Subroutines are no longer experimental in Perl 5.26 and up.)

      Since declaring two packages in the same lexical scope causes this "leakage" of lexically-scoped features across package boundaries, and this can cause confusion and sometimes subtle bugs, it's usually recommended to put each package declaration into its own lexical scope, in other words:

      { package Foo; our $var = "Hello"; sub func { print $var, "\n" } } { package Bar; print $Foo::var, "\n"; Foo::func(); } # Or, as of Perl 5.14: package Foo { ... } package Bar { ... }

      If you do this, it forces you to reach across package boundaries using more explicit syntax, as I've shown above. Yes, it's more verbose, I understand you don't want to prefix everything with Device::BCM2835::*. The usual mechanism to get symbols (package variables and subs, there is no difference there!) from one package to another is the import/export mechanism I showed previously, i.e. copying symbol table entries. I poked around a bit on CPAN to see if there's a module to hide the somewhat ugly code I showed, and maybe Symbol::Alias could be useful:

      package Foo { our $var = "Hello"; sub func { print $var, "\n" } } package Bar { use Symbol::Alias '$Foo::var' => 'var', 'Foo::func' => 'func'; print $var, "\n"; func(); }

      Or for your case: use Symbol::Alias map {("Device::BCM2835::$_"=>$_)} qw/ gpio_fsel gpio_set gpio_clr ... /;

        Thank you, this is a very informative reply, also for being patient with me. My Perls were version 24 and 22, so I was just a few versions short.

        A side note I didn't think about, can a scalar be substituted in a scalar name? I think it was strict refs that complains if you use a scalar as the name of a hash, which might be why the earlier example you showed me needed it (if following the same rules). If I could just do ${pi} = "biglonglibraryname::subthing::", I wouldn't have to breach scope, and I could get a short name. Thanks again.