BEGIN { %main::_shared_vars = ( the_very_global => \$the_very_global ); } INIT { package main; sub _iterate_packages_loop { my($stash,$name,$callback) = @_; $callback->($stash,$name); foreach (keys %{$stash}) { if (/::\z/ and $_ ne "main::") { _iterate_packages_loop($stash->{$_},$name.$_,$callback); } } }; sub _iterate_packages { _iterate_packages_loop(\%::,"main::",shift); } _iterate_packages(sub { $_[1] eq "main::" and return; while (my($k,$v) = each %::_shared_vars) { $_[0]->{$k} = $v; } }); } $the_very_global = "GLOBAL!\n"; print $the_very_global; package bar; print $the_very_global; package bar::foo; print $the_very_global; #### BEGIN { %main::_shared_vars = ( the_very_global => \$the_very_global ); } BEGIN { use Filter::Util::Call; use strict; my $_strict_import = \&strict::import; package strict; sub _add_to_stash { my $name = shift; no strict 'refs'; while (my($k,$v) = each %::_shared_vars) { # importing this way makes the variable # be considered "declared" for the purposes # of strict. *{$name."::$k"} = $v; } }; *strict::import = sub { # setup the package we are being called by _add_to_stash(scalar caller); filter_add(sub { my $status; while (($status = filter_read()) > 0) { _add_to_stash($1) while /package\s+([\w:]+)/g; last unless(/package\s*\z/); } return $status; }); goto &$_strict_import; }; }