package Acme::Asplode; use 5.012; use strict; use warnings; use Keyword::Simple (); use PadWalker (); use Text::Balanced (); use Carp; sub import { Keyword::Simple::define asplode => sub { my $ref = shift; $$ref =~ s/^\s+//; my $extracted; if ($$ref =~ /^\(/) { $extracted = Text::Balanced::extract_bracketed($$ref) or croak "usage: asplode (VARIABLES);"; $extracted =~ s/(^\(|\)$)//g; } else { ($extracted, $$ref) = ($$ref =~ /^([^;]+)(;.*)$/s) or croak "usage: asplode VARIABLES;"; } (my $globs = $extracted) =~ s/[\$\%\@]/*/g; $$ref = "our($extracted); local($globs) = Acme::Asplode::_callback(q($extracted));$$ref"; } } sub unimport { Keyword::Simple::undefine asplode => (); } sub _callback { my $vars = shift; $vars =~ s/(^\s*|\s*$)//g; my @vars = split /\s*,\s*/, $vars; my $MY = PadWalker::peek_my(2); my $OUR = PadWalker::peek_our(2); return map { exists $MY->{$_} ? $MY->{$_} : exists $OUR->{$_} ? $OUR->{$_} : croak "asplode($_) failed; caller has no $_ defined"; } @vars; } 'ASPLODE!';