|
From: Eric W. <scr...@gm...> - 2007-01-29 07:08:45
|
# from Mike Schilli
# on Sunday 28 January 2007 07:30 pm:
>On Fri, 26 Jan 2007, Eric Wilhelm wrote:
>> The issue is that the code never gets compiled. The @INC hook
>> sets[1] $INC{"foo/bar.pm"}, so any subsequent require()'s don't try
>> to load it. The errors will be equivalent to something like:
>>
>> mkdir -p foo/Time
>> echo "1;" > foo/Time/HiRes.pm
>> perl -Ifoo -e 'use Time::HiRes';
Sorry, that last line should have read
perl -Ifoo -e 'use Log::Log4perl'
Which should get you a huge pile of errors starting with:
Undefined subroutine &Time::HiRes::gettimeofday called
at /usr/.../Log/Log4perl/Layout/PatternLayout.pm
line 34.
Of course, nothing would work in this circumstance, but exactly the same
thing is happening with your module_available() call in the presence of
an @INC hook.
>> Because the @INC hook only returns a filehandle, to fully
>> re-implement require (which I don't suggest), you must
>> eval("$string") the contents of that.
>
>Can you send some perl code that shows the problem? I still don't
> understand what the problem is, especially where the @INC hook comes
> from.
Please see the attached demo. The @INC hook in par is basically
_find_par_internals(), which you can read here:
http://search.cpan.org/src/SMUELLER/PAR-0.972/lib/PAR.pm
If you're still not seeing what's wrong with calling those coderefs and
not eval($string)'ing the result, please read 'perldoc -f require'
again. "Note that these hooks are also permitted to set the %INC entry
corresponding to the files they have loaded."
>> My question is: why not eval {require Foo} ?
>Try this:
> $SIG{__DIE__} = sub { print STDERR "Die! What?\n"; exit 0 };
I can understand the concern, but if that is the only reason, then I
have to say it is bad trade-off to break a documented perl feature to
allow for improper usage of a discouraged one.
That is a poorly written die hook which didn't follow the documentation.
See perlfunc/die. Any well-behaved SIG{__DIE__} should have:
die @_ if $^S; # get out if we're in an eval
Though, you could always put local $SIG{__DIE__} in the eval if you're
feeling lenient. If you rework module_available() to use eval, that
would be a good place for it.
Note, the attached (academic) example will demonstrate the issue.
Calling it with no arguments means the first call to the hook is from
module_available(), with a command-line argument, we'll require
Sys::Hostname ourselves and module_available() will be happy.
Also attached is a patch which implements my proposed fix.
As I said, you could check whether $@ =~ /Can't locate $mod_path/, but
that's only if you think compilation errors should be propagated (hint:
put another curly around the "local $SIG{DIE}; eval {...}" chunk before
you throw an error so it propagates correctly.)
Hopefully, the break_log4perl.pl attachment can be easily adapted to
your test suite. Please let me know if there's anything else I can do
to help get this fixed.
Thanks,
Eric
--
"Left to themselves, things tend to go from bad to worse."
--Murphy's Corollary
---------------------------------------------------
http://scratchcomputing.com
---------------------------------------------------
|