Skip Menu |

This queue is for tickets about the Moose CPAN distribution.

Report information
The Basics
Id: 60585
Status: resolved
Priority: 0/
Queue: Moose

People
Owner: Nobody in particular
Requestors: mschwern [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 1.09
Fixed in: (no value)



Subject: Difficult for a non-Moose class to use a Moose role.
Let's say I'm refactoring Moose into a big legacy app. I refactor something to be a Moose::Role and then I want to use that role in a non-Moose class. I can't do C<< use Moose 'with'; with "MyRole"; >> because that will turn my non-Moose class into a Moose::Object subclass possibly messing up my inheritance chain. I can't do C<< use Moose::Util qw(apply_all_roles); apply_all_roles( __PACKAGE__, "MyRole" ); >> because that wants a MOPified class. apply_all_roles() (or something in its stack) could take my class name and make a metaclass object or whatever is necessary to make Moose take notice of it. This would make using Moose roles in non-Moose classes much easier.
Subject: Re: [rt.cpan.org #60585] Difficult for a non-Moose class to use a Moose role.
Date: Sat, 21 Aug 2010 09:14:07 +0200
To: bug-Moose [...] rt.cpan.org
From: Yuval Kogman <nuffin [...] cpan.org>
On 21 August 2010 06:34, Michael G Schwern via RT <bug-Moose@rt.cpan.org> wrote: Show quoted text
> I can't do C<< use Moose 'with';  with "MyRole"; >> because that will > turn my non-Moose class into a Moose::Object subclass possibly messing > up my inheritance chain.
Yes you can, just put it after any 'use base' or 'BEGIN { push our @ISA, ... }' and Moose will not add Moose::Object as a base class. If you wish to add Moose attributes later on, MooseX::NonMoose helps integrate Moose object construction as an extra step for another constructor, as opposed to being done in Moose::Object::new
Subject: Re: [rt.cpan.org #60585] Difficult for a non-Moose class to use a Moose role.
Date: Sat, 21 Aug 2010 03:24:03 -0700
To: bug-Moose [...] rt.cpan.org
From: Michael G Schwern <schwern [...] pobox.com>
On 2010.8.21 12:14 AM, Yuval Kogman via RT wrote: Show quoted text
> <URL: http://rt.cpan.org/Ticket/Display.html?id=60585 > > > On 21 August 2010 06:34, Michael G Schwern via RT <bug-Moose@rt.cpan.org> wrote: >
>> I can't do C<< use Moose 'with'; with "MyRole"; >> because that will >> turn my non-Moose class into a Moose::Object subclass possibly messing >> up my inheritance chain.
> > Yes you can, just put it after any 'use base' or 'BEGIN { push our > @ISA, ... }' and Moose will not add Moose::Object as a base class. > > If you wish to add Moose attributes later on, MooseX::NonMoose helps > integrate Moose object construction as an extra step for another > constructor, as opposed to being done in Moose::Object::new
I know I tried that and it didn't work. But I threw out that code, so I don't have an exact reproduction. I think what happened was I effectively did this: package NotMoose; use Moose 'with'; use base qw(Also::NotMoose); with 'SomeRole'; which looked fine but caused weird things to happen. I'm working on ugly legacy code that I don't completely understand and it wasn't immediately obvious that NotMoose's inheritance tree had been changed. I guess I was treating Moose as just a thing that exports stuff and not a pragma. I plea that I was doing this after an hour plus of debugging the "your methods aren't really methods" problem I reported earlier. Is the special behavior of Moose not causing inheritance from Moose::Object documented? The Moose docs are pretty clear that: Unless specified with "extends", any class which uses Moose will inherit from Moose::Object. How about: Unless specified with "extends", or the class already has a superclass, any class which uses Moose will inherit from Moose::Object. It would still be nice if apply_all_roles() worked on any class. -- Stabbing you in the face so you don't have to.
Subject: Re: [rt.cpan.org #60585] Difficult for a non-Moose class to use a Moose role.
Date: Mon, 23 Aug 2010 08:56:27 +0200
To: bug-Moose [...] rt.cpan.org
From: Yuval Kogman <nuffin [...] cpan.org>
On 21 August 2010 12:24, Michael G Schwern via RT <bug-Moose@rt.cpan.org> wrote: Show quoted text
>    package NotMoose; > >    use Moose 'with'; > >    use base qw(Also::NotMoose); >    with 'SomeRole';
Unfortunately it's order sensitive. This should work: package NotMoose; use base qw(Also::NotMoose); use Moose 'with'; with 'SomeRole; Show quoted text
> Is the special behavior of Moose not causing inheritance from Moose::Object > documented?  The Moose docs are pretty clear that: > >   Unless specified with "extends", any class which uses Moose will inherit >   from Moose::Object. > > How about: > >   Unless specified with "extends", or the class already has a superclass, >   any class which uses Moose will inherit from Moose::Object.
+1 Show quoted text
> It would still be nice if apply_all_roles() worked on any class.
Also +1
On Mon Aug 23 02:56:55 2010, NUFFIN wrote: Show quoted text
> > How about: > > > >   Unless specified with "extends", or the class already has a
> superclass,
> >   any class which uses Moose will inherit from Moose::Object.
Doc patch attached. Show quoted text
> > It would still be nice if apply_all_roles() worked on any class.
> > Also +1
This was discussed on #moose some centering on the wisdom of silently MOPifying non-MOP classes. Perigrin said this was tried and considered a bad idea but couldn't remember why. There was discussion about what sort of things you could and could not guess about a non-MOP Perl class and at what level of accuracy. It seems to me what's needed is a version of Class::MOP specifically designed to make intelligent guesses about non-MOP classes and, importantly, know what it cannot know. For example, the metaclass object of a non-MOP class would throw an exception if asked about its attributes. It can't make intelligent guesses about that. But it can speak about methods and superclasses. That would allow Moose to play nice with non-MOP classes while without overstepping its knowledge. It would also allow a non-MOP metaclass to use a different set of heuristics when figuring out things like what methods a class has, thus avoiding the "your method is imported so I'm going to ignore it" problem I reported in another ticket. Moose classes can be held up to a higher level of purity than regular Perl 5 classes.
Subject: 0001-Document-the-behavior-of-Moose-when-the-class-alread.patch
From ee5aa073ff69c2a3b9d833dfd7ec7259ed309cef Mon Sep 17 00:00:00 2001 From: Michael G. Schwern <schwern@pobox.com> Date: Mon, 23 Aug 2010 17:01:27 -0700 Subject: [PATCH] Document the behavior of Moose when the class already has a superclass --- lib/Moose.pm | 5 +++-- 1 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Moose.pm b/lib/Moose.pm index 0ba2a28..c23bd3f 100644 --- a/lib/Moose.pm +++ b/lib/Moose.pm @@ -367,8 +367,9 @@ Moose makes every attempt to provide as much convenience as possible during class construction/definition, but still stay out of your way if you want it to. Here are a few items to note when building classes with Moose. -Unless specified with C<extends>, any class which uses Moose will -inherit from L<Moose::Object>. +Unless specified with C<extends>, or the class already has a superclass +when Moose is used, any class which uses Moose will inherit from +Moose::Object. Moose will also manage all attributes (including inherited ones) that are defined with C<has>. And (assuming you call C<new>, which is inherited from -- 1.7.2.1
This has been fixed for a while.