clinton has asked for the wisdom of the Perl Monks concerning the following question:

I'm looking for the right OO approach to what I think amounts to perl 6 roles.

I have an Object base class which is inherited by other objects eg User, Group, Image. When each of these is loaded, they register their Type with the Object class so that any object can be retrieved using the parent class and blessed into the right package.

sub find { my $object = __PACKAGE__->retrieve_object($id); bless $object,$object->type->class
An Object can never exist on its own - it must always be blessed into a child class.

Group is a child class, and any object (including Groups) can be a member of a Group. Also, every object has a default Group (eg User automatically belongs to the group all_users).

Requirements

So, as I see it, I need to:
  1. register each child class with the Group class (so that it knows what the default group is, and
  2. have some form of code reuse so the the groups() method doesn't need to be included in each child class.
I thought of doing something like this:
use Group 'default_group'
Then in the package Group:
sub import { my $default_group = $_[1]; my $callpkg = caller(0); register_default_group($callpkg,$default_group); no strict 'refs'; *{$callpkg."::groups"} = \&groups; use strict;
Is this good, bad, ugly? Beauty, truth and love appreciated

thanks
clint

Replies are listed 'Best First'.
Re: Using perl 6 roles in perl 5
by dragonchild (Archbishop) on Jan 18, 2006 at 14:50 UTC
    Why not take a look at the four different implementations of roles that are out there right now and see if one is right for you.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      I should have looked - that was dumb. But looking at the code, they seem to be using a similar approach.

      Which is good.

      It just seems annoying to have to require a module whose purpose, in my code, I am accomplishing in a few lines.

      It's the old roll-your-own scenario. I'll insist on using my own code because I'm-only-using-it-in-this-one-place and probably 6 months down the line, I'll rip it out and replace it with one concise nicely written and document module installed from CPAN.

      But how else do we ever learn?

      Now where is my home-rolled templating system? No, not those ones, the other one.

        But how else do we ever learn?

        By improving on the current systems, not by rewriting them. Take a look at the code for Perl6::Roles. For the most part, it's just syntactic sugar. Class::Trait is more involved, but it's still just sugar, at its heart.

        If there's a feature you want or a performance benchmark you feel you need to hit, write a failing test and give it to the author. That way, everyone benefits from what you're trying to do.


        My criteria for good software:
        1. Does it work?
        2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
Re: Using perl 6 roles in perl 5
by stvn (Monsignor) on Jan 18, 2006 at 15:03 UTC

    Roles would be one way to solve this, but I think there are better ways.

    I have an Object base class which is inherited by other objects eg User, Group, Image. When each of these is loaded, they register their Type with the Object class so that any object can be retrieved using the parent class and blessed into the right package.

    I am not sure if this is the right approach. In OO, the Class is traditionally the element which "manages instances", not the Object. However, Perl 5's OO model being what it is, the distinction between class and object are very blurry. But either way, this is all irrelvant since I assume you are not looking to create a domain specific object metamodel to solve you problem.

    I would suggest that you instead use the Factory pattern here, which is not all that different from what you are doing, except you are calling your factory "Object". Then within your Factory you can handle all the constraints (singleton or not singleton) and relations (all classes are associated with a group) between your objects as just "configuration" within the factory. This approach would easily fufill all your stated requirements.

    -stvn
      You're absolutely right - that is what I'm doing. My only experience of OO is through Perl, so forgive me if my terminology is shaky.

      When I said When each of these is loaded, they register their Type with the Object class so that any object can be retrieved using the parent class and blessed into the right package., I really meant that each sub class registers with the parent class, which I have called Object.

      And which is, as you say, a factory class. It handles the auto-generated accessor methods, the required attribute checking when saving an object, loading, caching and saving objects etc.