Clear questions and runnable code
get the best and fastest answer
In the discussion concerning Seeking inside-out object implementations, several monks expressed various reasons for their reluctance to use inside-out objects. Here's the list I gathered from that thread:
I don't want to use inside-out objects because:
Further, as the author of Object::InsideOut, I will speak to specifics concerning that module where appropriate.
Hash-based objects are the standard. Using a different object API may lead to maintainability issues.The argument is basically that all Perl programmer's know how to use hash-based objects, and that if I use a support module like Object::InsideOut, then anyone else that tries to read/maintain my code will have to learn about inside-out objects, in general, as well as the specifics of the support module. This is obviously something to consider when looking at using inside-out objects, and needs to be weighed against inside-out objects' advantages.
As with any new paradigm, it will take time for inside-out objects to become generally accepted, however, I am confident that they will. Their inclusion in PBP will definitely speed up the process. Eventually, someone will write a tutorial on inside-out objects for inclusion with the main Perl distribution. Thus, as time goes by, the argument above will start to lose some of its weight.
Inside-out object classes aren't compatible with hash-based object classes.They aren't compatible in the same way as other hash-based object classes, true, but that doesn't mean you can't work with them at all.
One simple approach to inheriting from hash-based classes is to use the hash-based object as is, and then use its refaddr as the key for storing data inside the derived class. Some inside-out object support modules use this approach. However, this approach doesn't support multiple inheritance, and the use of refaddr requires addition code for thread-safety (given that the hash-based class must be thread-safe as well).
Object::InsideOut has recently been enhanced to support subclassing of hash-based object classes (referred to as foreign inheritance in its docs), and it does support multiple inheritance. Further, Object::InsideOut is thread-safe.
Inside-out objects are just another kludge on top of Perl's already kludgy OO mechanisms.Well, Perl never claims to be a pure OO language, and arguments as to its merits are rather pointless. It is what it is. Use it, or don't. My personal stand follows from the P in Perl standing for practical: Perl's OO interface gets the job done when it's needed. I find the ability to mix OO and procedural programming, as needed, to be one of Perl's greatest strengths.
As to inside-out objects being another kludge, I would argue against the use of that label. Inside-out objects is just another paradigm. They use standard Perl to do the same job but in a different manner, complete with its own strengths and weaknesses.
I haven't had any problems using hash-based objects. The encapsulation and compile-time checking advantages of inside-out objects aren't important enough to induce me to use them.To be clear, encapsulation for inside-out objects prevents the overwriting of hash-keys that can occur with inheritance in hash-based object classes.
The compile-time checking comes about because the fields in inside-out objects are hashes or arrays, and not hash-keys. Misspelled hash-keys are not caught at compile-time, and may or may not be caught at runtime. Misspelled hash or array names are caught at compile-time.
Now for smaller systems, these advantages may be of less importance to a single programmer. However, for larger projects with multiple coders, these advantages should be given much more thought. In fact, inside-out objects resulted from considering how to overcome just these problems with hash-based objects. Obviously, they are very important to some.
The encapsulation provided by inside-out objects is unenforcable because the source code is available.It is true that deliberate circumvention of any OO system is possible given the source code. If such totalitarian controls are a requirement of your system, then perhaps you need to consider using something other than Perl.
The point of encapsulation with inside-out objects is to prevent the collision of data (i.e., hash-keys) that can occur with hash-based object classes. It adds safety, but doesn't prevent deliberate circumvention.
Inside-out objects require a DESTROY method, and I don't what to have to remember to write one each time I create an inside-out class.Various inside-out object support modules, including Object::InsideOut, handle this for you automatically, so this becomes a non-issue if you use one of them.
There are too many alternative inside-out object support modules that aren't compatible with each other.This criticism can be applied to just about any functionality for which CPAN modules have been written: CPAN and CPANPLUS; ExtUtils::MakeMaker, Module::Build and Module::Install; and more.
As with anything, as time goes on, certain implementations will become more accepted than others depending on their features, robustness, support, and so on. Personally, I have been putting in a lot of effort in all these area to make Object::InsideOut as usable as possible to the Perl community.
I'm leery of the 'magic' the inside-out object support modules do 'under the covers'. There may be bugs or they may lead to unexpected problems when interacting with other modules.With the source code available, you can see what is being done, if needed. However, as I see it the proof is in the pudding. If the support modules does what you want it to and thereby meets your needs without causing problems and incompatibilities, then what difference does it make how it does it.
As for bugs, a good test suite and good author support lessen the probability and potential impact of encountering problems in your own development. For example, there are currently no open bugs for Object::InsideOut, and any reported bugs have been corrected in less than one day.
Likewise, incompatibilites can be overcome with good author support. For example, when I first released Object::InsideOut, I was informed that having a CHECK block would make it incompatible with mod_perl. Within a day, I posted an new version that eliminated this incompatibility.
I tried module Foo::Bar, and had problems with it so I gave up on trying to use inside-out objects.This sort of thing can happen with any module. Giving up is not the answer, however. If you weren't able to get support from the module's author, you could try another. Obviously, you were interested enough to look at inside-out objects in the first place. A bad module doesn't mean the underlying concept (i.e., inside-out objects) is bad.
You can't serialize inside-out objects either in general, or using Data::Dumper or Storable.It is true that inside-out objects do not automatically support serialization. Once again, however, some support modules do provide serialization capabilities. For example, Object::InsideOut does provide object serialization and deserialization capabilites, and has recently been enhanced to support serialization using the Storable module.
Inside-out objects are not thread-safe because they usually use refaddr as the key for storing object data.Making inside-out objects thread-safe is not a trivial process, but it can be done. Object::InsideOut is thread-safe, and even goes further by providing support for threads::shared.
Remember: There's always one more bug.