in reply to Re^2: OO in Perl 5: still inadequate
in thread OO in Perl 5: still inadequate

I don't understand #3, accessors are what allow ignorance of super classes but you can always look inside a hash accessor and bypass it if you want. #2 I'll deal with in a more general argument in a minute and #1 is included in my "bold claim".

Here's my bold claim: any class is subclassable without "knowledge" of it's implementation.

I'll explain the quotes around "knowledge" in a minute.

All that's required is an inside-out class builder that keys off something like the refaddr of the object and doesn't really care what kind of blessed refs. I'm pretty sure such builders exist, although I can't name one (I can't name any i-o object builder :). If they don't I don't see any great obstacle to building one. Voila - subclassing without knowledge of the superclass's implementation. These classes are themselves subclassable in the same way. All attribute manipulation would be done via accessor methods generated by the builder class, that way encapsulation is advisroy not mandatory.

So assuming you agree that the above scheme exists or almost exixts, it's time to address "knowledge". Does the above need to know the type of the blessed reference? No. Does it need to know the contents? No. How about the names of any methods? In general, no, however we have to avoid trampling over any undocumented methods in the superclass because they could be called by a method in the superclass and do something completely unexpected.

These undocumented methods could be a problem but consider the requirement for advisory encapsulation. What this means is that undocumented methods must remain accessible and so it's impossible to avoid this problem. You either want them to be accessble or you don't, you can't have both (this answers #2 above, although for hash based objects, using __PACKAGE__."keyname" for keys also helps a lot).

So I think it's quite straight forward to achieve both goals for this definition of "knowledge". You cannot{1} avoid having some knowledge if you want to retain advisory encapsulation.

Example: class Shape uses blessed glob refs. We want to sublcass it for Rectangle which we do, adding 4 undocumented accessors for _Point1, _Point2, Point3, _Point4 and 1 documented Corners. The values for these are stored inside-out and are looked up based on the refaddr of the object. No knowledge of Shape was required apart from that we mustn't add any methods that override Shape's undocumented methods. We can in turn subclass this but we shouldn't override it's undocumented accessors _Point{1-4}.

Basically if you want advisory encap then can't have total ignorance of the superclass. Given that, the rest is easy.

{1} Well actually you almost can but it involves wrapping all methods in something that checks the caller to see if the call is coming from inside the superclass in which case we dispatch to the old method, otherwise the new but that's exceedingly ugly and slow and still isn't 100% reliable (think a callback doen from inside the superclass that ends up calling one of these methods, do we give it the inner or outer version?).

Replies are listed 'Best First'.
Re^4: OO in Perl 5: still inadequate
by simonm (Vicar) on Jan 21, 2006 at 04:51 UTC
    All that's required is an inside-out class builder that keys off something like the refaddr of the object and doesn't really care what kind of blessed refs. I'm pretty sure such builders exist, although I can't name one...

    You can do this with Class::MakeMethods. (Cf. Class::MakeMethods::Template::InsideOut.)

Re^4: OO in Perl 5: still inadequate
by brian_d_foy (Abbot) on Jan 21, 2006 at 06:30 UTC

    Not every class is subclassable (although it would be nice if they were), knowledgable or otherwise. Some people do odd things like blessing an object into a hard-coded class (so you don't get to decide which class the object ends up in), have some factory-like behavior going on where the object ends up in a particular class, and lots of other things. Lots of code I see doesn't pass the null-subclass test.

    If you're doing weird wrapper or adapter things, you really aren't subclassing.

    --
    brian d foy <brian@stonehenge.com>
    Subscribe to The Perl Review

      Yes. There's an implicit requirement on the classes we're discussing to be subclassable in the first place, otherwise the discussion is pointless. We may as be talking about the number of vertices in polygons and allowing polygons to include circles.

      s/\bclass\b/class (which must be subclassable to start with)/g

        If you limit the set of classes your claim applies to, you can't use the word "any". Your bold claim is too bold :)

        --
        brian d foy <brian@stonehenge.com>
        Subscribe to The Perl Review
Re^4: OO in Perl 5: still inadequate
by Aristotle (Chancellor) on Jan 21, 2006 at 15:48 UTC

    The point was that inside-out objects done using lexical variables are themselves strongly encapsulated. So you can subclass any class without knowing the implementation of the superclass, but your encapsulation is no longer advisory.

    (Well, until xdg made his “err, package vars anyone?” point further down in the thread and I headdesked.)

    Makeshifts last the longest.