Skip Menu |

This queue is for tickets about the Log-Log4perl CPAN distribution.

Report information
The Basics
Id: 24884
Status: resolved
Priority: 0/
Queue: Log-Log4perl

People
Owner: Nobody in particular
Requestors: EWILHELM [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in:
  • 0.42
  • 0.43
  • 0.44
  • 0.45
  • 0.46
  • 0.47
  • 0.48
  • 0.49
  • 0.50
  • 0.51
  • 0.52
  • 1.00
  • 1.01
  • 1.02
  • 1.03
  • 1.04
  • 1.05
  • 1.06
  • 1.07
  • 1.08
  • 1.09
Fixed in: (no value)



Subject: L4p::Util::module_available() breaks @INC hook functionality
if(ref $dir eq "CODE") { return 1 if $dir->($dir, $relpath); One should not call @INC subrefs directly without evaluating the code in the filehandle on their return value. If the @INC hook sets a %INC entry ($INC{$relpath}), any subsequent requires will not attempt to load the module. Calling Log::Log4perl::module_available("Sys::Hostname") then behaves as if you had done: $INC{"Sys/Hostname.pm"} = 1; require Sys::Hostname; That is, require will not try to load the module. Reimplementing require is way too complicated, and this version is incomplete. Please just use eval {require} to decide whether the module is available.
Subject: break_log4perl.pl
#!/usr/bin/perl use warnings; use strict; BEGIN { my $s_hn = `$^X -e 'require Sys::Hostname; print \$INC{"Sys/Hostname.pm"};'`; chomp($s_hn); $s_hn or die "just hardcode that for me then"; #warn "$s_hn"; unshift(@INC, sub { my ($s, $mod) = @_; # demo purposes only ($mod =~ m#Sys/Hostname.pm#) or return; open(my $fh, '<', $s_hn) or die; $INC{'Sys/Hostname.pm'} = $s_hn; return($fh); }); } BEGIN { @ARGV and require Sys::Hostname; # let require do it right } use Log::Log4perl; # vim:ts=2:sw=2:et:sta
Subject: log4perl_require_fix.patch
--- Log-Log4perl-1.08/lib/Log/Log4perl/Util.pm 2006-02-28 20:01:45.000000000 -0800 +++ Log-Log4perl-1.08-fix/lib/Log/Log4perl/Util.pm 2007-01-28 22:56:20.000000000 -0800 @@ -8,38 +8,16 @@ # This has to be here, otherwise the following 'use' # statements will fail. ################################################## - my($full_name) = @_; + my($mod_name) = @_; - my $relpath = File::Spec->catfile(split /::/, $full_name) . '.pm'; + my $mod_path = + join('/', (split /::/, $mod_name)) . '.pm'; - # Work around a bug in Activestate's "perlapp", which uses - # forward slashes instead of Win32 ones. - my $relpath_with_forward_slashes = - join('/', (split /::/, $full_name)) . '.pm'; - - return 1 if exists $INC{$relpath} or - exists $INC{$relpath_with_forward_slashes}; - - foreach my $dir (@INC) { - if(ref $dir) { - # This is fairly obscure 'require'-functionality, nevertheless - # trying to implement them as diligently as possible. For - # details, check "perldoc -f require". - if(ref $dir eq "CODE") { - return 1 if $dir->($dir, $relpath); - } elsif(ref $dir eq "ARRAY") { - return 1 if $dir->[0]->($dir, $relpath); - } elsif(ref $dir and - ref $dir !~ /^(GLOB|SCALAR|HASH|REF|LVALUE)$/) { - return 1 if $dir->INC(); - } - } else { - # That's the regular case - return 1 if -r File::Spec->catfile($dir, $relpath); - } - } - - return 0; + eval { + local $SIG{__DIE__}; # in case they don't know about $^S + require($mod_path); + }; + return($@ ? 0 : 1); } ##################################################
Finally resolved this one by using require() and a local __DIE__ handler, similar to what you suggested. Thanks! http://github.com/mschilli/log4perl/commit/189e67b0bc69556210052ec74f1fed703aca6d33