From 89ebef591125868427922d475ff76e3d1f40fccc Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Wed, 24 Jul 2013 13:23:10 -0400 Subject: convert to Devel::OverrideGlobalRequire (fixes #4) --- lib/circular/require.pm | 88 ++++++++++++++----------------------------------- 1 file changed, 24 insertions(+), 64 deletions(-) diff --git a/lib/circular/require.pm b/lib/circular/require.pm index 5c0ee4b..7d9c042 100644 --- a/lib/circular/require.pm +++ b/lib/circular/require.pm @@ -4,10 +4,8 @@ use warnings; # ABSTRACT: detect circularity in use/require statements use 5.010; -use Package::Stash; -# XXX would be nice to load this on demand, but "on demand" is within the -# require override, which causes a mess (on pre-5.14) -use B; +use Devel::OverrideGlobalRequire; +use Module::Runtime 'module_notional_filename'; =head1 SYNOPSIS @@ -65,35 +63,20 @@ or our %loaded_from; our $previous_file; -my $saved_require_hook; my @hide; -sub _find_enable_state { - my $depth = 0; - while (defined(scalar(caller(++$depth)))) { - my $hh = (caller($depth))[10]; - next unless defined $hh; - next unless exists $hh->{'circular::require'}; - return $hh->{'circular::require'}; - } - return 0; -} +Devel::OverrideGlobalRequire::override_global_require { + my ($require, $file) = @_; -sub _require { - my ($file) = @_; - # on 5.8, if a value has both a string and numeric value, require will - # treat it as a vstring, so be sure we don't use the incoming value in - # string contexts at all - my $string_file = $file; - if (exists $loaded_from{$string_file}) { - my @cycle = ($string_file); + if (exists $loaded_from{$file}) { + my @cycle = ($file); my $caller = $previous_file; while (defined($caller)) { unshift @cycle, $caller unless grep { /^$caller$/ } @hide; - last if $caller eq $string_file; + last if $caller eq $file; $caller = $loaded_from{$caller}; } @@ -102,39 +85,16 @@ sub _require { warn "Circular require detected:\n " . join("\n ", @cycle) . "\n"; } else { - warn "Circular require detected in $string_file (from unknown file)\n"; + warn "Circular require detected in $file (from unknown file)\n"; } } } - local $loaded_from{$string_file} = $previous_file; - local $previous_file = $string_file; + local $loaded_from{$file} = $previous_file; + local $previous_file = $file; - return $saved_require_hook->($file) - if $saved_require_hook; - - if (ref(\$file) eq 'VSTRING') { - # require 5.8.1 - return eval sprintf("CORE::require %vd", $file) || die $@; - } - elsif (!(B::svref_2object(\$file)->FLAGS & B::SVf_POK)) { - # require 5.008 - # note: we are careful above to never use $file in any potential string - # contexts - this is what the $string_file variable is for - return eval "CORE::require $file" || die $@; - } - elsif (defined((caller(1))[6])) { - # ugh, base.pm checks against the regex - # /^Can't locate .*? at \(eval / to see if it should suppress the error - # but we're not in an eval anymore - # fake it up so that this looks the same - my $str = B::perlstring($file); - return eval "CORE::require($str)" || die $@; - } - else { - return CORE::require($file); - } -} + $require->(); +}; sub import { # not delete, because we want to see it being explicitly disabled @@ -147,27 +107,27 @@ sub unimport { @hide = ref($params{'-hide'}) ? @{ $params{'-hide'} } : ($params{'-hide'}) if exists $params{'-hide'}; - @hide = map { /\.pm$/ ? $_ : _mod2pm($_) } @hide; + @hide = map { /\.pm$/ ? $_ : module_notional_filename($_) } @hide; - my $stash = Package::Stash->new('CORE::GLOBAL'); - my $old_require = $stash->get_symbol('&require'); - $saved_require_hook = $old_require - if defined($old_require) && $old_require != \&_require; - $stash->add_symbol('&require', \&_require); $^H{'circular::require'} = 1; } -sub _mod2pm { - my ($mod) = @_; - $mod =~ s+::+/+g; - $mod .= '.pm'; - return $mod; +sub _find_enable_state { + my $depth = 0; + while (defined(scalar(caller(++$depth)))) { + my $hh = (caller($depth))[10]; + next unless defined $hh; + next unless exists $hh->{'circular::require'}; + return $hh->{'circular::require'}; + } + return 0; } =head1 CAVEATS This module works by overriding C, and so other modules -which do this may cause issues if they aren't written properly. +which do this may cause issues if they aren't written properly. See +L for more information. =head1 BUGS -- cgit v1.2.3