Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Way to use Moo::Role to extend non-Moo class?

by einhverfr (Friar)
on Nov 13, 2013 at 09:42 UTC ( #1062361=perlquestion: print w/replies, xml ) Need Help??
einhverfr has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks;

I am trying to simplify some code here and would like to take a set of interfaces in one class and turn them into a Moo role.

I tries with and extends and neither one would work. It seems I can use base but that leads to a lot of problems. Any ideas?

I would like to do something like this (pseudocode):

package foo; sub foo { print "foo\n"; } package bar; use Moo::Role; extends 'foo';

I can't figure out how to accomplish this though. Is it even reasonably possible?

Replies are listed 'Best First'.
Re: Way to use Moo::Role to extend non-Moo class?
by Arunbear (Prior) on Nov 13, 2013 at 10:49 UTC
    What is the purpose of your bar package? If you wanted to reuse methods from package foo without refactoring foo itself, you could use method forwarding:
    package bar; use Moo::Role; has 'foo' => ( is => 'rwp', handles => [qw/foo/], # put other methods to be delegated here );
    Then any class that consumes this role will be able to call the methods of foo that you set up delegation for.

    If you were wanting to split up the methods into different roles, you could e.g. move the foo() method to its own role:

    package Foo::Role; sub foo { print "foo\n"; }
    Then if bar wanted to 'extend' this with other methods:
    package bar; use Moo::Role; with 'Foo::Role'; # ... other methods
      In my case it won't be that simple, but it's very helpful in terms of thinking through the problem. Thanks.
Re: Way to use Moo::Role to extend non-Moo class?
by tobyink (Abbot) on Nov 13, 2013 at 12:04 UTC

    Roles don't "extend" classes. Subclasses extend classes.

    This will work:

    package Foo { sub new { bless {}, shift; } sub foo { print "foo\n"; } } package Bar { use Moo; # NOT Moo::Role extends "Foo"; }

    ... but if the constructor for class Foo is any more complicated than the above, you'll need to write a FOREIGNBUILDARGS method for Bar to tell Bar's constructor what argument need to be passed along to Foo's constructor.

    use Moops; class Cow :rw { has name => (default => 'Ermintrude') }; say Cow->new->name

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1062361]
Approved by marto
Front-paged by toolic
and the rats come out to play...

How do I use this? | Other CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (8)
As of 2018-06-18 19:42 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (110 votes). Check out past polls.