http://qs321.pair.com?node_id=792629


in reply to Re^6: A working strategy to handle AUTOLOAD, can(), and (multiple) inheritance without touching UNIVERSAL?
in thread A working strategy to handle AUTOLOAD, can(), and (multiple) inheritance without touching UNIVERSAL?

Interesting. This is exactly why I think a module is needed. It is too complicated to be reimplemented and at least my first version was flawed or incomplete. I'd be more inclined to trust a module if the documentation and test suite give the impression of the module being robust.
Yeah. If there was such a module I would use it. But if everyone followed my advice there would be no early adopters and so it would never reach the required maturity. I suspect all the perl brains (who could cut through this) are currently working on perl6.
>>> This means you have to craft your own solution, but it is fairly simple. That sounds a bit contradictory. :-)
Not at all contradictory. If you craft your own solution you are not trying to come up with an all encompassing solution but rather your are cutting your goals back to what matters in your circumstances.
How about return if $method eq 'DESTROY'; in AUTOLOAD?
Isn't this obscurantist? If you want to implement DESTROY why not just define one. Are you arguing that once you start using AUTOLOAD everything should pass through AUTOLOAD?
Would that include looking at UNIVERSAL::can to find "real" methods?
This is exactly what I do not trust. It seems that one class is trying to be very clever. It just feels wrong.
  • Comment on Re^7: A working strategy to handle AUTOLOAD, can(), and (multiple) inheritance without touching UNIVERSAL?

Replies are listed 'Best First'.
Re^8: A working strategy to handle AUTOLOAD, can(), and (multiple) inheritance without touching UNIVERSAL?
by lodin (Hermit) on Sep 01, 2009 at 13:38 UTC

    I do not want to implement DESTROY, that's the point. :-) What I want to avoid is to croak with "missing method" during object destruction. The reason I want to make an exception for DESTROY in AUTOLOAD is the following scenario:

    { package Foo; sub new { ... } sub DESTROY { ... } } { package Bar; our @ISA = Foo::; sub AUTOLOAD { ... } sub DESTROY {} # Oops. }
    I want to think as little as possible, and by adding the exception in AUTOLOAD it always works and is future proof should you add any DESTROY later.
    This is exactly what I do not trust. It seems that one class is trying to be very clever. It just feels wrong.
    I'm not sure what you are referring to. Is it the call to UNIVERSAL::can? If UNIVERSAL::can($obj, 'foo') returns a value then that is what $obj->foo will call by the definition of UNIVERSAL::can. So naturally I would not want my can to return anything else if I want to be consistent.

    In fact I was afraid I was not being clever enough and was missing something. The only thing my can does differently from any method that adds to a super method is that it checks UNIVERSAL::can:

    • If $obj->$method will not call a regular method and if this class autoloads $method: go to it.
    • If not: see what the next class says. (UNIVERSAL is considered the top class; explicitly added as the return value only because next::method ignores UNIVERSAL.)
    AUTOLOAD's only exception is about DESTROY:
    • If this class autoloads the method: go to it.
    • If not: ask the next AUTOLOAD.
    • If no next AUTOLOAD: croak, unless the method is DESTROY.

    lodin