If Foo inherits from Bar, and Bar defines an AUTOLOAD, then both undefined functions and methods in Foo can trigger Bar::AUTOLOAD. In some situations Bar::AUTOLOAD really
wants to do different things on a function call than a method call. (Like issue a warning for a function, and try to handle methods.)
Which raises the issue of how you tell them apart.
Unfortunately caller doesn't do the trick. One approach that I thought of was Devel::Caller, but its test suite fails on my machine. (And it has documented serious limits.) There is a warning Use of inherited AUTOLOAD for non-method %s() is deprecated that is triggered exactly when I want to distinguish the cases. I don't know how to get at that, and it might be turned off. (Turning it on and trapping it could work, if I could think of a way to guarantee that behaviour.)
That leaves heuristics. If the first argument is blessed (testable with Scalar::Util) then it is a pretty safe bet that it is meant as a method call. Conversely if the first argument is the name of a package that exists, I'd guess that that is meant as a method call. What would people prefer to see assumed, though, if the string is one that plausibly could be a package (ie it matches a pattern like /^\w+(?:::\w+)*(?:::)?\z/). Should I assume that it is a method call on a package that doesn't yet exist, or assume that it is a function call? Or don't assume and make my error message ambiguous??
For the curious, this is for a proof of concept UNIVERSAL::AUTOLOAD_CAN, as described in Re: Re: Why breaking can() is acceptable.