in reply to Is there any (performance) benefit to importing functions?
The documentation will (well, should) explain which functions are "exported" by default, and which ones you have to ask for. If not, look in the module's code, and in the @EXPORT array, these are the ones exported by default. The @EXPORT_OK are ones you need to specifically request when loading the module. One can also use %EXPORT_TAGS hash to create tags that can bundle certain groups of functions.
For example, my Bit::Manip distribution exports none of its functions by default, you have to ask for them individually, or you can use the :all tag to load them all in bulk:
use Exporter; our @ISA = qw(Exporter); our @EXPORT_OK = qw( bit_get bit_set bit_clr bit_bin bit_count bit_mask bit_tog bit_toggle bit_on bit_off ); our %EXPORT_TAGS; $EXPORT_TAGS{all} = [@EXPORT_OK];
My WiringPi::API goes one step further, and does use tags to bundle. The distribution is a wrapper of a C library. You can read the export implementation on lines 11-61, but the gist of it is that I provide three tags:
our @EXPORT_OK = (@wpi_c_functions, @wpi_perl_functions); our %EXPORT_TAGS; $EXPORT_TAGS{wiringPi} = [@wpi_c_functions]; $EXPORT_TAGS{perl} = [@wpi_perl_functions]; $EXPORT_TAGS{all} = [@wpi_c_functions, @wpi_perl_functions];
The first tag exports the functions with their original C names (camelCase). The second exports the Perl wrapped names (snake_case). The third, is pretty clear, exports the lot of them. Looking at it now, I don't know why I didn't just set all to @EXPORT_OK, but I digress...). To use them in a use statement, you'd specify them as :wiringPi, :perl or :all.
It's considered bad practice to blindly export all subs by default, as there is high risk that you'll clobber an existing symbol table name. In my App::CopyrightImage module, I have a single public function, which I do export by default:
our @EXPORT = qw(imgcopyright);
The documentation explicitly states we export the one function automatically.
To further, I've even gone beyond using Exporter, and just pee'd all over the user's symbol table to stuff in a function:
sub import { my ($class, %opts) = @_; $self = __PACKAGE__->_new(%opts); my $sub_name = $opts{sub_name} ? $opts{sub_name} : 'plugins'; { no warnings 'redefine'; no strict 'refs'; my $pkg = (caller)[0]; *{"$pkg\::$sub_name"} = \&_plugins; } }
...but that is something rarely done (and shouldn't be done unless there's a very good reason). Of course, that documentation also explicitly and clearly states we do this.
As far as benchmarking, I don't really care. It's startup cost, a one-time thing. To me, benching that would pretty much be far too much optimization without enough benefit. However, if you do bench it, please do post results.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Is there any (performance) benefit to importing functions?
by choroba (Cardinal) on Feb 10, 2018 at 22:24 UTC | |
by stevieb (Canon) on Feb 10, 2018 at 22:26 UTC | |
by haukex (Archbishop) on Feb 10, 2018 at 23:04 UTC |