Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Re: [Moose] extends(...) throws "Subroutine redefined" warnings

by kcott (Archbishop)
on Oct 08, 2015 at 04:58 UTC ( [id://1144139]=note: print w/replies, xml ) Need Help??


in reply to [Moose] extends(...) throws "Subroutine redefined" warnings

G'day muba,

While I appreciate you've only shown a minimal example, and there could be a lot more going on than I'm aware of, my gut feeling is that you have a design flaw here. I say that because parent classes shouldn't know, or care, about their subclasses.

If I change your test one-liner to something a little more substantial, I get much the same as ++Athanasius did in his response:

$ perl -MMyClass -le 'print SubClass::->new()->get_subclass_object()' MyClass already has a metaclass, but it does not inherit Moose::Meta:: +Class (Class::MOP::Class=HASH(0x7f918c72e440)). at /Users/ken/perl5/p +erlbrew/perls/perl-5.22.0t/lib/site_perl/5.22.0/darwin-thread-multi-2 +level/Moose/Exporter.pm line 484 Moose::import('Moose') called at MyClass.pm line 3 MyClass::BEGIN at MyClass.pm line 3 eval {...} at MyClass.pm line 3 require MyClass.pm at -e line 0 main::BEGIN at MyClass.pm line 3 eval {...} at MyClass.pm line 3 BEGIN failed--compilation aborted at MyClass.pm line 3. Compilation failed in require. BEGIN failed--compilation aborted.

By swapping the order in which the two modules are loaded in MyClass.pm, i.e.

package MyClass; use Moose; use SubClass;

your problem disappears:

$ perl -MMyClass -le 'print SubClass::->new()->get_subclass_object()' SubClass=HASH(0x7fc4f2bb4148)

However, I make absolutely no guarantees that this will not cause other problems with your complete code (which I haven't seen).

If I remove the use SubClass; from MyClass.pm, and load SubClass.pm, instead of MyClass.pm, in the test:

$ perl -MSubClass -le 'print SubClass::->new()->get_subclass_object()' SubClass=HASH(0x7fb6698259a8)

the compile-time error is eradicated.

I have a superclass (MyClass), which creates instances of a subclass on demand."

Change &get_subclass_object to be more generalised. Something like:

sub get_subclass_object { my $class = ref $_[0]; return $class->new; }

Create another subclass (OtherSubClass.pm) for testing:

package OtherSubClass; use Moose; extends 'MyClass'; 1;

Now you can instantiate whatever subclasses you want:

$ perl -MSubClass -le 'print SubClass::->new()->get_subclass_object()' SubClass=HASH(0x7fae2280f258)
$ perl -MOtherSubClass -le 'print OtherSubClass::->new()->get_subclass +_object()' OtherSubClass=HASH(0x7fa721030da8)

You can create as many subclasses as you want. MyClass knows nothing about them. All subclasses use the same method: &MyClass::get_subclass_object.

The design flaw is now eradicated.

The SYNOPSIS of the base Moose documentation has an example showing the use of extends. Read on for more information on extends in that documentation (which has links to further details).

— Ken

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1144139]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others admiring the Monastery: (8)
As of 2024-04-18 14:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found