in reply to UNIVERSAL::can and autoloaded methods

Welcome to dynamic language world, where the land moves out from under your feet.

Use CGI::Simple. A lot of magic and trickery conflicts in Perl. Even after it is fixed, new magic and trickery will conflict. Not everything will always work with everything else. Tieing has a long history of conflicts and still has some caveats.

can() itself is typical - a static language would know at compile time whether or not a method exists in a class. No run time test is needed. Not only can methods appear due to AUTOLOAD, classes might act as generators of sort, creating methods by binding closures to data and assigning them names as a sort of template. Some classes act as object black holes, where all method calls are errors. Other as white holes, where all method calls silently return. And numerous other things.

Parrot plans to add to isa() and can() a has() to test attributes. This compounds the problem - ineffectual tools can sometimes distract you from real solutions. If you want to play the object game, use interfaces. Both isa() and can() share a common problem that stems from their run time nature: they encourage explicit type case analysis. Any conditional logic that depends on which class you have should be part of the class itself. Otherwise, each new class introduced breaks things. C has for a long time checked that switch() statements when used on enum values check for each possible enum value and warn otherwise. This is the same problem with a different solution - introducing new values shouldn't break old code. It takes some object-think to get into the mode of shuffling code into objects so that objects respond how they like when a certain kind of thing is desired. Objects should respond to general requests rather than specific demands. If you're thinking in terms of adding to a counter using an accessor, you're thinking wrong. Think different. Instead, think of notifying of arrival of email or whatever you were counting. The object may count it as originally intended, or it might present a event listerns interface to broadcast notifications. Or perhaps other things. Anyway, remember, use methods as a way of notifying objects of information or event, not demanding that something be done, especially not demanding it be done a certain way.

Perl lets you extend classes after the fact by revisiting namespaces. B::Generate, for instance, extends B to make the accessors put/get instead of merely get. Obviously B couldn't be extended in two seperate ways at the same time, but remember that you're still in the dynamic language world. Adding new methods is safer. Safer still is super class abstraction, where the root class is the most general case of objects of that type.

Dynamic languageism is the heart of the matter. You can skirt it in these different ways, some more elegant than others, some more appropriate, but Grace Hopper's ghost will raise from the grave and haunt you for 24 hours if you keep doing things the way you've always done them for the reason that you've always done them that way. To make sure that only the correct types can possibily worm their way to where they're expected exclusive of everything else, use strict type checking. Don't panic! You don't turn all dynamicism off, it is done on a method by method, variable by variable basis. Perl can inspect your code and warn if there is a possibility that something other than a CGI object or some subclass will arrive at a place where you only want a CGI object. With a few caveats (things missing from the typesafety module), any warnings generated represent a design short coming in your program from an object oriented perspective. No, objects aren't like guns where any 5 year old can just pick it up and use it. The language features that support objects are less than half of the battle. Knowing how to use them is far more important. Few people write good object oriented Perl but many large fine C programs written with a good grasp of objects exist - Postgres, the Linux kernel, MySQL, Apache.

Dynamic languages are powerful, but when the question comes to sanity, structure, and order, a bit of the static might be just what the doctor ordered. Everything in its time in place - preferably all at the same time under Perl though =)

-scott

P.S.: I'm not a regular reader and I'm not one for discussions. Reply to this, of course, but if you want to get my attention, please email me - scott@slowass.net. Thanks.
  • Comment on Re: UNIVERSAL::can and autoloaded methods