http://www.perlmonks.org?node_id=228329


in reply to A simple import() for those special moments

It will simply export any symbol, regardless of its type (function, hash, array etc) whose name matches the pattern in $exported - in this case all the variables declared with vars and the foo_bar function.

One should perhaps also point out that variables declared with our() will be exported too. I've realized that some people are confused about what our():ed variables really are.

But something really nasty can happen. It might export whole packages! Indeed, it's not very likely, but there's still a risk. Example:

{ package Foo::foo_bar; our $bar = 'BAR'; } use Foo; print $foo_bar::bar; # 'BAR'!

There's also a bug in the code. If the caller is a nested package, e.g. A::B, then it won't work. This is due to $main::{$caller}->{$_}. The keys in %main:: (or %:: for short) that end in :: are just the first part of the package name. This behaviour nests, so A::B's (the ' is not a package delimiter here ;)) symbol table is found in %{$main::{'A::'}{'B::'}}.

This being a copy-n-paste candidate make those hardcoded Foos hurt an eye of mine. I'd really like see __PACKAGE__ utilized here. Each time you copy this you'll (or someone else who rip this code) have to change those package names and that increases the risk of getting a bug.

To the real question; if you should be wary of this. Unless you've made it very general, i.e. works for all callers and packages, I would. Unless you're totally sure there's no bug, I would. There will be quite a few modules to patch after a year or two if you just copy it.

Below is my version, with minimal changes from the original:

sub import { my $caller = caller() . '::'; do { require Carp; Carp::croak("You cannot specify an import list to " . __PA +CKAGE__); } if @_ > 1; no strict 'refs'; *{"$caller$_"} = *{__PACKAGE__ . "::$_"} for grep !/::$/ && /$exported/, keys %{__PACKAGE__ . '::'} +; }

I don't claim this version to be bug free either. :)

Btw, how about making this into a module and calling it Exporter::Pattern? (Or Exporter::Regex(p), but I like Exporter::Pattern better.) The interface would be quite simple:   use Exporter::Pattern qr/PATTERN/;

ihb