Don't ask to ask, just ask | |
PerlMonks |
comment on |
( [id://3333]=superdoc: print w/replies, xml ) | Need Help?? |
No, I wasn't listening, this is my first time really looking at
PerlMonks. I was in the middle of mucking about with Tie::Cache::LRU
and found myself writing a virtual base class and all these
enforcement methods and such. So rather than make a one-off (heavens,
no!) I slapped together Class::Virtual.
So first off, Class::Virtual *doesn't* require each subclass to call a check function directly (although re-reading the documentation, I can see why one would think that. Will correct.) The check methods are there for code auditing purposes, reporting, internal use and subclasses of Class::Virtual (as we'll see in a moment). I'll change the docs to de-emphisize them and emphisize the real purpose of the module. The major difference I can see between Class::Virtual and AbstractClass is C::V does its work at run-time whereas AC works at compile-time. C::V waits until you actually call an unimplemented virtual method before it yells. This might seem silly (since it would have blown up anyway) but it does provide a more informative error. Also, doing the checks at compile-time would cause half my modules to blow up (being the poster boy for method auto-generation that I am). However, not to be outdone... That should emulate the compile-time behavior of AbstractClass and its mucking with bless(). (BTW Your prototype is wrong). And feel free to steal the closure trick to generate the import() instead of the eval(). I can flesh this out an ship it with Class::Virtual if you'd like. So, digging into the internals... a few things bother me about AbstractClass. First, it hijacks import(). Why should an OO module need an import() routine? Well, AbstractClass needs one. Lots of hybrid OO/functional modules need it (Class::Fields for one). Its too important to take away. Another problem with the import() route is its brittleness. Consider the following... Ooops. And this is a perfect valid and common, way of subclassing which defeats AbstractClass. Consider this, too... base.pm does not call import() (and rightly so). AbstractClass defeated. Another, @ABSTRACT_METHODS bothers me. Magical global variables bother me, doubly so in OO contexts. Triply so when you start putting this magical global into other packages. Maybe if you put it into @{$base.'::__ABSTRACT_METHODS'} or something. I take the class data route instead. Overriding bless... I haven't decided if that's Evil or not. I'd rather define a default new() method that does the same thing. Besides, even if you do manage to generate an object from a virtual class, its going to explode the first time you use it. Another, with AbstractClass, SomeAbstractClass->can("some_virtual_method") returns false. With Class::Virtual it returns true (but if you try to use the method returned it will explode). I guess this is a design decision. I don't totally understand why AbstractClass doesn't work with MI, but Class::Virtual doesn't have any problem (god forbid, I can't live without MI). Finally, in the Class::Virtual scheme, virtual base classes are subclasses of Class::Virtual. I like this because of its synchronicity and because it allows the behavior of Class::Virtual to be altered (as for Class::Virtually::Abstract). In reply to Re: AbstractClass
by Anonymous Monk
|
|