develooper Front page | perl.perl5.porters | Postings from November 2009

Re: Carp/overload problem exposed by mktables

Thread Previous | Thread Next
From:
karl williamson
Date:
November 29, 2009 20:45
Subject:
Re: Carp/overload problem exposed by mktables
Message ID:
4B134DBC.1050908@khwilliamson.com
Nicholas Clark wrote:
> 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 :-)

Well that seems to work.  Thank you.
> 
> 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.

Yet another way to plug the loophole is to put Scalar::Util::refaddr in 
the core.  My recollection, which I think is correct, is that consensus 
had been reached; it's just a matter of finding someone to do it. 
Perhaps it could be put on the Todo list, as some sort of encouragement.
> 
> 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About