summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2011-01-25 15:09:37 -0600
committerJesse Luehrs <doy@tozt.net>2011-01-25 15:09:37 -0600
commit64c74c4d2d2718a2059cc4dbc1626e4eb2b068db (patch)
tree5351e0f3eebb510cd2dab4ee7ca871036fd1bd14
parent47b406fc2ae8a479813ff55cc172abcf6596b919 (diff)
downloadcircular-require-64c74c4d2d2718a2059cc4dbc1626e4eb2b068db.tar.gz
circular-require-64c74c4d2d2718a2059cc4dbc1626e4eb2b068db.zip
initial implementation
-rw-r--r--dist.ini1
-rw-r--r--lib/circular/require.pm38
-rw-r--r--t/01-basic.t40
-rw-r--r--t/01/Bar.pm4
-rw-r--r--t/01/Baz.pm4
-rw-r--r--t/01/Foo.pm4
6 files changed, 91 insertions, 0 deletions
diff --git a/dist.ini b/dist.ini
index 1b9171c..8a4db95 100644
--- a/dist.ini
+++ b/dist.ini
@@ -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;