Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

Ovid
  (email not shown publicly)
http://publius-ovidius.livejournal.com/
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Friday October 12, 2007
02:43 AM

Where's the Bug?

[ #34657 ]

You know, there are plenty of modules out there which expect you to inherit from them to gain their functionality. Perhaps the worst offender is Exporter. Your non-OO modules are expected to inherit? Sheesh.

If you're writing an abstract base class, it makes perfect sense to use inheritance, but please stop and ask yourself if there's any other way you can provide the desired functionality. Particularly with multiple inheritance (MI), Perl's default method resolution order is awful (C3 method resolution allieves the pain but doesn't make it go away).

Of course, anything which forces MI should be viewed with great suspicion (I'm lookin' at you, Catalyst). MI is so well known to be problematic that many languages with OO facilities simply forbid it.

So, let's say I need a factory class, with class data, don't want to worry about missing methods (like Smalltalk and Sqeak) and want handy method generation.

Where's the bug?

  package Hate;

  # Hmm, better sort these so they're easy to read ...

  use base qw(
    Class::Accessor
    Class::BlackHole
    Class::Data::Inheritable
    Class::Factory
  );

Now how much of that behavior could you duplicate without forcing inheritance on people?

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • It’s certainly common for non-OO modules to inherit from Exporter, and it matches the first example in the Exporter synopsis. But the second example shows an alternative:

    package MyModule;
    use Exporter qw<import>;
    our @EXPORT_OK = qw<...>;
    I recently changed a large codebase to use that approach instead of inheritance.
  • Well, you could duplicate all of this functionality and require no MI at all using Moose and the Class::MOP meta level (the only forced inheritance being Moose::Object, but even that is optional). This all too common abuse of inheritance was one of the main reasons I wrote Moose the way I did. Having the meta layer allows you to add behavior to classes which belong with the class and not with any object instances created by the class (your classic OO "seperation of concerns"). Some of this behavior could e

    • Heh. Point taken :)

      It's also worth noting that two of those classes provide their own constructor. Hmm, which should I use? Can I use both? Must I use both? All the more reason to provide that functionality without inheritance.

      Speaking of Moose (which I really like, though I've yet to have used it in a production environment, how's it's performance coming along?

      • Speaking of Moose (which I really like, though I've yet to have used it in a production environment), how's it's performance coming along?

        Well, the startup cost is still kind of high because we do so much in the compile phase, but if you are in a persistent environment that is a moot point. The runtime speed is basically "fast enough" for most people and making your class immutable only increases that.

        The most basic accessors are actually faster than Class::Accessor, of course if you add type constrai