Dallaylaen has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear esteemed monks,

I would like to be able to add per-package configuration parameters to the use statement of my module, but also let the module export some functions. Something like:

use My::Module { hairiness => 2 }, qw(:core frobnicate); frobnicate( $foo ); # with hairiness = 2

I came up with the following:

package My::Module; use parent qw(Exporter); our @EXPORT_OK = qw(frobnicate); our %EXPORT_TAGS = ( core => [], ); sub import { # or do it via a foreach and extra @args array my %setup = map { %$_ } grep { ref $_ eq 'HASH' } @_; @_ = grep { ref $_ ne 'HASH' } @_; $_[0]->per_package_setup( scalar caller, %setup ); goto \&Exporter::import; }; my %per_package_conf; # or our?.. sub per_package_setup { my ($self, $target, %options) = @_; # setup for target }; sub frobnicate { my $x = shift; return $x; # TODO actually use parameters here };

I don't want to remove exporter because it does the job and is predictable (and also has export tags).

Are there better/shorter/more common ways to do the same?

Thank you.

Replies are listed 'Best First'.
Re: Mixing configuration options and exports in 'use' statement
by pryrt (Abbot) on Dec 22, 2017 at 16:34 UTC

    Don't know if there's a "better" way (for whatever definition of "better"), but it seems a pretty good method to me.

    To get your example to work, i had to add a comma between the hashref and the export list; and, of course, define dummy versions of your missing %EXPORT_TAGS and frobnicate().

    use My::Mod qw(:core frobnicate), { hairiness => 2 }; frobnicate( arg1 => 'val1' ); # with hairiness => 2
    package My::Mod; use parent qw(Exporter); our @EXPORT_OK = qw(frobnicate); our %EXPORT_TAGS = (core => []); sub import { # or do it via a foreach and extra @args array my %setup = map { %$_ } grep { ref $_ eq 'HASH' } @_; @_ = grep { ref $_ ne 'HASH' } @_; $_[0]->per_package_setup( scalar caller, %setup ); goto \&Exporter::import; }; use Data::Dumper; sub per_package_setup { my ($self, $target, %options) = @_; # setup for target print STDERR "$self->per_package_setup($target, VAR1):\n"; print STDERR Dumper \%options; %self::OPTS = %options; }; sub frobnicate { print map { "frobnicate($_)\n"} @_; printf "{ %-20s => %s }\n", $_, $self::OPTS{$_} foreach sort keys +%self::OPTS; } 1;
      Oh, didn't check it before posting. :(
Re: Mixing configuration options and exports in 'use' statement
by haukex (Archbishop) on Dec 22, 2017 at 19:38 UTC

    I don't think you need goto, here's a snippet that I've often used:

    use parent 'Exporter'; sub import { # fiddle with @_ all you like here __PACKAGE__->export_to_level(1, @_); return; }
      Nice! Somehow I never did RTFM that far...