On Sat, Nov 28, 2009 at 06:37:15PM -0700, karl williamson wrote:
> I'm not sure what to do here. When Carp is called by mktables from an
> object that has overloading (stringify, I suspect), Carp tries to call
> Scalar::Util::refaddr, and fails because we are running under miniperl.
> It gives the message:
> Attempt to reload Scalar/Util.pm aborted.
> Compilation failed in require at lib/overload.pm line 95.
>
> I think it actually does the stringify correctly, but fails in the
> backtrace.
>
> Any suggestions? I suppose I could just not use carp.
My test case:
./miniperl -Ilib -MCarp -e '{ package A; use overload q{""} => sub {local $^D="t"; Carp::carp("Oops")};} print bless {}, "A"'
fails slightly differently:
...
Can't load module B, dynamic loading not available in this perl.
(You may need to build a new perl executable which either supports
dynamic loading or has the B module statically linked into it.)
at lib/Scalar/Util/PP.pm line 15
Compilation failed in require at lib/Scalar/Util/PP.pm line 15.
BEGIN failed--compilation aborted at lib/Scalar/Util/PP.pm line 15.
Compilation failed in require at lib/Scalar/Util.pm line 21.
Compilation failed in require at lib/overload.pm line 95.
suggesting that it's this bit of Carp:
# Transform an argument to a function into a string.
sub format_arg {
my $arg = shift;
if (ref($arg)) {
$arg = defined($overload::VERSION) ? overload::StrVal($arg) : "$arg";
}
calling overload:
sub AddrRef {
my $package = ref $_[0];
return "$_[0]" unless $package;
local $@;
local $!;
require Scalar::Util;
my $class = Scalar::Util::blessed($_[0]);
my $class_prefix = defined($class) ? "$class=" : "";
my $type = Scalar::Util::reftype($_[0]);
my $addr = Scalar::Util::refaddr($_[0]);
return sprintf("$class_prefix$type(0x%x)", $addr);
}
and that's failing.
The work-around hack would seem to be to add
undef $overload::VERSION;
to mktables :-)
Given that we removed Carp::Heavy, with the reasoning that it's wrong for an
error reporting module to require more resources at error reporting time, as
it might fail and hence eat the error message, we seem to be in the same
trap here. The test on $overload::VERSION seems logical though - if overload
is not loaded, there's (in theory*) no need to check for overloading. But I
can't see a clean way to plug this loophole, short of a tight coupling
between Carp and overload such that if either spots that the other is already
loaded, then it requires Scalar::Util, to make sure that it's there for error
reporting.
Nicholas Clark
* In theory, sure. In practice, XS code can create overloaded objects:
$ ./perl -Ilib -MCarp -e 'sub a {carp("Hello world")} a($^V)'
Hello world at -e line 1
main::a('v5.11.2') called at -e line 1
$ ./perl -Ilib -MCarp -e 'use overload; sub a {carp("Hello world")} a($^V)'
Hello world at -e line 1
main::a('version=HASH(0x10081e720)') called at -e line 1
Thread Previous
|
Thread Next