develooper Front page | perl.perl5.porters | Postings from February 2018

Re: [perl #132902] Blead Breaks CPAN: Class::Std

Thread Previous | Thread Next
February 25, 2018 02:42
Re: [perl #132902] Blead Breaks CPAN: Class::Std
Message ID:
On 25 February 2018 at 02:40, Father Chrysostomos via RT
<> wrote:
> On Sat, 24 Feb 2018 15:51:03 -0800, demerphq wrote:
>> On 25 Feb 2018 02:01, "Father Chrysostomos via RT" <
>>> wrote:
>> > I don’t like the current state of the code in, but I can’t say I
>> > have a better suggestion off the top of my head.  I have not thought it
>> > through thoroughly yet.  Let me just outline my concerns, before I forget
>> > them, and later if I have time I might come up with a patch:
>> >
>> > if ($in_recurse || do{ local $in_recurse = 1; $pack->can("((") }) {
>> >
>> > This will only work on newer perls (5.16+ iirc), since older ones used (),
>> > not ((.  And I think even current perl allows XS modules to register
>> > overloading via just (), without ((.  I need to check.
>> We can add a check for () as well.
>> > ‘can’ is really not the right thing to use.
>> Can you explain why? Since overloads are inherited it seems there is no
>> choice.
> The text that follows was meant to be the explanation.  can and AUTOLOAD go together.  Since overloading does not use AUTOLOAD, using can to detect overloading can be problematic.

Yeah I read that text, but I am still not seeing the connection the way you do.

So, it makes sense to override can if you use AUTOLOAD.

And overload's dont trigger AUTOLOAD. That is clear.

But, it doesnt seem to obvious to me that that means that we shouldnt
use can() for finding inheritable methods. Overload  is *designed* so
this works. That is why the methods are registered the way they are.
(At least that is what the comments in overload indicate to me.)

It seems like you are saying something like: "Because the main reason
to override can() is to work properly with AUTOLOAD, people often
implement their can overrides without accounting for overload subs,
and thus most of them are buggy, thus we shouldn't use can()".

Which doesn't seem logical to me, even if perhaps it is practical.

Why not simply say "We should document that can() overrides need to be
robust to overload calls"? I mean, i would consider any can() that
doesn't handle overload subs buggy, why don't you? It seems a strange
basis to argue we shouldn't use the one thing we have available to use
(Zefram mentions there is internal code that exactly what we want but
it is not exposed).

To me that there are buggy can() implementations out there is a
problem for those buggy can() implementations, and maybe an indication
we need better docs on this, not an argument to avoid can() for this
type of purpose.

>> >   Overriding ‘can’ makes sense in the presence of AUTOLOAD, but since
>> > overloading bypassing AUTOLOAD, it should be bypassing ‘can‘ as well.  This
>> > is why implements its own ‘can’.  Perhaps should be
>> > loaded unconditionally when Carp is loaded (it is more lightweight than
>> > Carp, after all).  Then theoretically one could use overload::Overloaded,
>> > but unfortunately old versions have the same ‘can’ bug that will cause the
>> > recursion.
> Not just recursion.  Look at the test I added in e6bb0a40852.

Thanks, i will look.

>> > Maybe calling overload::mycan directly is the solution.
>> If Carp unilaterally loads overload we don't need to use can at all. The
>> only reason we use it is to avoid loading overload when we don't need to.
>> I already suggested that this policy was counter productive and the only
>> reason I didn't change was that you expressed an opinion that we should be
>> able to keep it.
>> If you no longer care about loading overload then the patch becomes trivial.
> Well, since Carp is used *everywhere*, I believe it should remain as lightweight as possible.

Overload is widely used as well. I also am not that sympathetic to the
lightweight argument, i don't see a single module used for this kind
of purpose as a problem, especially when you consider how much code we
have in Carp to deal with these types of issues.

>  Now that I’ve had a chance to look at the code in more detail, I see that it only occurs for stack traces.  I am loath to force another module to be loaded, considering that many quick scripts never use stack traces.

I bet you couldn't even see the extra module load in normal benchmarks
of any kind of non-trivial script.

>  But loading on demand in that case is itself problematic, since Carp is often called when things are in an inconsistent state.  You shouldn’t risk dying when trying to load something in order to report an error.  (Yes, this actually happened.  That’s why Carp::Heavy was eliminated.)

I totally agree. No argument there at all. See
02c84d7f0f97e083f5d8ea9856488f3ede09364f for an example of me patching
for this objective. ;-)

> That said, I’m still on the fence about it.  I know Zefram cares about this sort of thing, too, so I would ask him which is the best approach:
> • Go ahead and load unconditionally.  It’s already much smaller than Carp.
> • Copy & paste mycan into Carp.  It’s just seven lines or so (but we need two versions depending on the perl version).

Isnt mycan slow compared to the internals version? Maybe in modern
perls we should expose the internals function Zefram mentioned:

(05:57:51) Zefram: annoyingly, the exact thing you want is available
as a Perl op, method_named, but you can't get at that op in isolation
through Perl source code

That way BOTH carp and overload could use it in newer perls.

I don't really want to see Carp slowed down massively just because we
haven't documented how people should implement UNIVERSAL::can
overrides properly. That seems just wrong.

>> > This is a real can of worms.
>> A real mycan of worms?
>> Yves
> s/v//r is my answer. :-)


BTW, going forward there is another solution, expose unoverloaded
stringification via Internals:: or perhaps scalar::

It wont help older builds, but in the long run it would avoid needing
overload at all.


perl -Mre=debug -e "/just|another|perl|hacker/"

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About