I'm sure I missed something in the docs, but I'm trying to use parameterized 
roles to set up a group of classes that delegate to corresponding classes, but 
the methods that I'm delegating won't necessarily be known at compile time.

    package My::Role;
    use MooseX::Role::Parameterized;
    parameter 'bridge' => (
        isa      => 'My::Class',
        required => 1,
    );
    role {
        my $p = shift;
        has 'bridge' => (

            is      => 'rw',
            isa     => 'My::Class',
            default => sub {$p->bridge},
            handles => [$p->bridge->meta->get_attribute_list],
        );
    };

And the following class:

    package My::Class;
    use Moose;

    has [qw/foo bar/] => (
        is       => 'ro',
        isa      => 'Str',
        required => 1,
    );

The idea is that I want to create a *bridge* from one class to another, 
delegating off to the other class's attributes (this allows me to reuse 
behavior from an existing set of DBIx::Class results without inheriting 
unwanted behavior). So with a stub class:

    package Some::Other::Class;
    use Moose;

What I want is to have all instances of Some::Other::Class delegate 'foo' and 
'bar' to the bridge (My::Class). To do that, I need to do this:

    my $object = Some::Other::Class->new;
    my $meta   = My::Role->meta;
    $meta->apply(
        $object,
        bridge => My::Base->new(
            foo => 'this is foo',
            bar => 'this is bar',
        )
    );
    say $object->foo;
    say $object->bar;
    __END__
    this is foo
    this is bar

The problem: I don't want to apply this to every instance of the class, I want 
to apply it to the class itself, but if I use a class name as the first 
argument to 'apply', it throws an exception saying "You must pass in an blessed 
instance".

If the above wasn't clear, this should help. I have a class with a method like 
this:

    sub load_objects { 
        my $self    = shift; 
        my $base    = $self->object_base; 
        my @classes = map { "${base}::$_" } $self->schema->sources; 
 
        my @errors; 
        foreach my $class (@classes) { 
            unless ($self->_can_load($class)) {
                $self->_build_class($class);
            }

            # apply parameterized role to $class now,
            # not to every instance of $class

        } 
    }

The intent is to have DBIx::Class result source objects get "wrapped" by 
regular objects which can then be composed as I want, rather than how the 
database is forcing it (e.g., Customer can inherit from Person or be a role, 
rather than a "might_have" relationship such as $person->customer)

However, if the wrapping class isn't written, we can still have a useful stub 
class built on the fly that provides the attributes that the dbic object does, 
thus avoiding the trouble of writing the wrapper classes for an entire 
hierarchy for classes that don't need it (the same way that we don't write 
customer resultset classes unless we need to customize their behavior).

I hope that made sense.

Cheers,
Ovid
--
IT consulting, training, international recruiting
     
  http://www.allaroundtheworld.fr/.
Buy my book! - http://bit.ly/beginning_perl
Live and work overseas - http://www.overseas-exile.com/

Reply via email to