diff options
author | Jesse Luehrs <doy@tozt.net> | 2011-01-25 15:09:37 -0600 |
---|---|---|
committer | Jesse Luehrs <doy@tozt.net> | 2011-01-25 15:09:37 -0600 |
commit | 64c74c4d2d2718a2059cc4dbc1626e4eb2b068db (patch) | |
tree | 5351e0f3eebb510cd2dab4ee7ca871036fd1bd14 | |
parent | 47b406fc2ae8a479813ff55cc172abcf6596b919 (diff) | |
download | circular-require-64c74c4d2d2718a2059cc4dbc1626e4eb2b068db.tar.gz circular-require-64c74c4d2d2718a2059cc4dbc1626e4eb2b068db.zip |
initial implementation
-rw-r--r-- | dist.ini | 1 | ||||
-rw-r--r-- | lib/circular/require.pm | 38 | ||||
-rw-r--r-- | t/01-basic.t | 40 | ||||
-rw-r--r-- | t/01/Bar.pm | 4 | ||||
-rw-r--r-- | t/01/Baz.pm | 4 | ||||
-rw-r--r-- | t/01/Foo.pm | 4 |
6 files changed, 91 insertions, 0 deletions
@@ -7,3 +7,4 @@ copyright_holder = Jesse Luehrs dist = circular-require [Prereqs] +Package::Stash = 0.22 diff --git a/lib/circular/require.pm b/lib/circular/require.pm index e69de29..882b2b7 100644 --- a/lib/circular/require.pm +++ b/lib/circular/require.pm @@ -0,0 +1,38 @@ +package circular::require; +use strict; +use warnings; +use Package::Stash; + +my %seen; +my $saved; + +sub _require { + my ($file) = @_; + if (exists $seen{$file} && !$seen{$file}) { + warn "Circular require detected: $file (from " . caller() . ")\n"; + } + $seen{$file} = 0; + my $ret = $saved ? $saved->($file) : CORE::require($file); + $seen{$file} = 1; + return $ret; +} + +sub import { + my $stash = Package::Stash->new('CORE::GLOBAL'); + if ($saved) { + $stash->add_package_symbol('&require' => $saved); + } + else { + $stash->remove_package_symbol('&require'); + } +} + +sub unimport { + my $stash = Package::Stash->new('CORE::GLOBAL'); + my $old_require = $stash->get_package_symbol('&require'); + $saved = $old_require + if defined($old_require) && $old_require != \&_require; + $stash->add_package_symbol('&require', \&_require); +} + +1; diff --git a/t/01-basic.t b/t/01-basic.t new file mode 100644 index 0000000..5ddde3f --- /dev/null +++ b/t/01-basic.t @@ -0,0 +1,40 @@ +#!/usr/bin/env perl +use strict; +use warnings; +use lib 't/01'; +use Test::More; + +no circular::require; + +{ + my $warnings; + local $SIG{__WARN__} = sub { $warnings .= $_[0] }; + use_ok('Foo'); + is($warnings, "Circular require detected: Foo.pm (from Baz)\nCircular require detected: Baz.pm (from Bar)\n", "correct warnings"); + clear(); +} + +{ + my $warnings; + local $SIG{__WARN__} = sub { $warnings .= $_[0] }; + use_ok('Bar'); + is($warnings, "Circular require detected: Baz.pm (from Foo)\nCircular require detected: Bar.pm (from Baz)\n", "correct warnings"); + clear(); +} + +{ + my $warnings; + local $SIG{__WARN__} = sub { $warnings .= $_[0] }; + use_ok('Baz'); + is($warnings, "Circular require detected: Baz.pm (from Foo)\n", "correct warnings"); + clear(); +} + +sub clear { + for (qw(Foo Bar Baz)) { + delete $::{$_}; + delete $INC{"$_.pm"}; + } +} + +done_testing; diff --git a/t/01/Bar.pm b/t/01/Bar.pm new file mode 100644 index 0000000..f7d7f72 --- /dev/null +++ b/t/01/Bar.pm @@ -0,0 +1,4 @@ +package Bar; +use Baz; +sub quux { } +1; diff --git a/t/01/Baz.pm b/t/01/Baz.pm new file mode 100644 index 0000000..c70c7aa --- /dev/null +++ b/t/01/Baz.pm @@ -0,0 +1,4 @@ +package Baz; +require Foo; +require Bar; +1; diff --git a/t/01/Foo.pm b/t/01/Foo.pm new file mode 100644 index 0000000..5e5d6c3 --- /dev/null +++ b/t/01/Foo.pm @@ -0,0 +1,4 @@ +package Foo; +use Baz; +sub quux { } +1; |