in reply to Difficulty with Object::InsideOut

Just for confirmation, I see the same test results when I run your code.

However, taking a look at Object::InsideOut's documentation I noticed this:

Object::InsideOut implements inside-out objects as anonymous scalar references that are blessed into a class with the scalar containing the ID for the object ...

The underlined part implies that an object must access its body (the scalar ref) to get its id. This is something a real inside-out object never does. The salient point about the inside-out model is that nothing is stored in the object itself, so that the body is never accessed. This, and only this, gives inside-out classes the indepencence from object implementation that makes inheritance "just work", the way it does in dedicated OO languages.

In other words, Object::InsideOut doesn't give you true inside-out objects. You're probably better off if you base your class on one of the other implementations of inside-out classes on CPAN (Class::InsideOut or Class::Std), or implement it directly.

Anno

Update:I erroneously accused Class::InsideOut of not giving you "true inside-out objects". Corrected to say Object::InsideOut. Class::InsideOut does produce true inside-out objects. Apologies to those involved, and thanks to shmem who caught the error.

Update: Made links of some references to classes

Replies are listed 'Best First'.
Re^2: Difficulty with Object::InsideOut
by herveus (Prior) on Mar 24, 2007 at 17:44 UTC
    Howdy!

    Object::InsideOut uses lexical arrays to store attribute values, so it needs to store the array index somewhere. The "inside-outness" comes from the fact that even if you know the index, you can't get to the arrays to break encapsulation. That doesn't violate "inside-outness".

    I was trying to use the ability to have a class inherit from a foreign (non-Object::InsideOut) package. In this case, I'm wrapping a Set::Scalar::Valued object, and I want a Morsulus::Catalog::SetOf object to be able to inherit the methods from Set::Scalar::Valued. According to the docs for Object::InsideOut, I simply call the inherit method and pass it an instance of the foreign object. In my example, I'm also going so far as to keep that object as an attribute of my SetOf object.

    I elected to try Object::InsideOut because it offers a richer set of features than Class::InsideOut, and it's not doing things that Class::Std does that have bad implications (CHECK blocks come to mind as potentially problematic).

    Oh, and I looked at the test suite for Object::InsideOut to see how it tests the foreign inheritance functionality. I don't see the difference, and I can't discern just what additional arguments inherit is expecting.

    yours,
    Michael
      I was trying to use the ability to have a class inherit from a foreign (non-Object::InsideOut) package.

      I am not amazed that it is just this feature that is problematic in Object::InsideOut. Inheritance from a non-inside-out class is exactly where a full inside-out class exploits its agnosticism with respect to its body. Any actual object can be substituted and still allow access to the data that are implemented inside-out style. Once you use the body, for anything at all, this feature goes away. In the case of Object::InsideOut, the body must contain the id as a scalar, or behave as if it did. I don't know how Object::InsideOut solves the problem, but it can't be straightforward.

      The inside-out technique brings two things that are lacking in traditional Perl OOP: encapsulation and (almost) unimpeded inheritance. Of the two, the implicatrions on inheritance are far more important. Not because of any theoretical reasons, but because the lack of encapsulation hasn't had any serious consequences. People don't access the innards of an object directly, and that is that.

      The lack of free inheritance has hindered the development of OOP in Perl. You want to subclass an existing class from CPAN? Well, you can't without getting intimately involved in the implementation of the prospective superclass. If your class is inside-out, or if the superclass is, the problem goes away. That makes a big difference.

      There is deplorably little code reuse among the classes on the CPAN. When inside-out becomes more common, that could change.

      Anno

        Howdy!

        Actually, I think that Object::InsideOut does manage it, but there is something going on in Set::Scalar that makes the behavior really weird. Set::Scalar does a lot of overloading, and that may be part of the problem. I'm not sure that the problem lies within Object::InsideOut.

        Object::InsideOut tries to provide a clean way to drag a "foreign" class into the inheritance tree so that you can freely inherit from non-Object::InsideOut classes. I think I managed to run into a pathological case.

        Inside-out objects can, as a general case, be any sort of blessed reference. The key characteristic is that the attributes of the object are not stored in that reference. The ID of the object is not one of the visible attributes, and I think the innards of Object::InsideOut make the referent read-only as well.

        Class::InsideOut includes a discussion of what was available on CPAN to support inside-out objects, including brief critical assessments of each, noting strengths and weaknesses. Object::InsideOut fared well, and I don't see this little exercise in digging into packages and experimenting with -MO=concise as contradicting the essence of that.

        yours,
        Michael