Re: MooseX::NonMoose for Roles?
On Fri, 28 Jan 2011 22:36:30 +0100, Zbigniew Lukasiak wrote: > I am testing here if it could be made easy to use a library with > multiple inheritance in Moose. Assuming that the additional base > classes already work in a way similar to Moose Roles. If you want your classes to be roles, actually do the work to turn them into roles. Otherwise just use MI the way you're currently doing, which I assume involves next::method or similar. Don't try to do both. It might work for simple cases, but it will end in tears. hdp.
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 10:25 PM, Chris Prather wrote: > On Fri, Jan 28, 2011 at 4:13 PM, Stevan Little > wrote: >> On Jan 28, 2011, at 4:06 PM, Zbigniew Lukasiak wrote: >>> >>> On Fri, Jan 28, 2011 at 9:35 PM, Karen Etheridge wrote: On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: > > Are there any sane options for building Moose::Roles out of Non Moose > classes? > > Or maybe it is trivial? The thing about roles is they aren't instantiated, so you can't really do: package MyApp::Role::Foo; use base 'Some::Other::Class'; use Moose::Role; ...because there is no way to call up the inheritance tree to get at methods in Some::Other::Class. However, if you imported functions from that class into your role, you can make them available in your role just the same as if you had implemented them into your role itself. Perhaps can you describe an example of what you want to do? >>> >>> Well - that's what I was thinking, but: >>> >>> use strict; >>> use warnings; >>> >>> { >>> package Aa; >>> use Exporter 'import'; >>> our @EXPORT_OK = qw(foo); >>> >>> sub foo{ >>> print "foo\n"; >>> } >>> } >>> { >>> package Bb; >>> use Moose::Role; >>> Aa->import( 'foo' ); >>> >>> sub baz { >>> foo(shift); >>> } >>> >>> sub bar { >>> print "baaar\n"; >>> } >>> } >>> { >>> package Cc; >>> use Moose; >>> with 'Bb'; >>> } >>> >>> my $c = Cc->new(); >>> $c->bar; >>> $c->baz; >>> $c->foo; >>> >>> >>> prints: >>> >>> baaar >>> foo >>> Can't locate object method "foo" via package "Cc" at a.pl line 37. >>> >>> So there is something missing, foo is not recognized as a method. >> >> No, because 'foo' is not a method, it is an imported function from another >> package. Class::MOP checks the STASH of the CV to find out if it is a native >> of that package and if not, it assumes it is an imported function and >> therefore ignores it. >> >> It is a feature, not a bug :) >> >> - Stevan > > Additionally doing this is *really* nasty action-at-a-distance. Trying > to explain what exactly is going on to someone who may or may not > grasp the wonderful nuances that are Perl's package stashes and > importation rules is not nearly as easy as explaining Attributes and > Delegation. Think of the sanity of your downstream maintenance > programmers. Yeah - OK - I was not proposing that this should work, that was just an example explaining the difficulties. Anyway - let's go back to the core: { package Aa; sub foo{ print "foo\n"; } } { package Bb; use Moose::Role; ... } { package Cc; use Moose; with 'Bb'; } my $c = Cc->new(); $c->foo; What should go into the '...' there to make it work? Would it be possible to make it also working if Aa inherited foo from some other superclass? I am testing here if it could be made easy to use a library with multiple inheritance in Moose. Assuming that the additional base classes already work in a way similar to Moose Roles. -- Z
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 4:13 PM, Stevan Little wrote: > On Jan 28, 2011, at 4:06 PM, Zbigniew Lukasiak wrote: >> >> On Fri, Jan 28, 2011 at 9:35 PM, Karen Etheridge wrote: >>> >>> On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: Are there any sane options for building Moose::Roles out of Non Moose classes? Or maybe it is trivial? >>> >>> The thing about roles is they aren't instantiated, so you can't really >>> do: >>> >>> package MyApp::Role::Foo; >>> >>> use base 'Some::Other::Class'; >>> use Moose::Role; >>> >>> ...because there is no way to call up the inheritance tree to get at >>> methods in Some::Other::Class. However, if you imported functions from >>> that class into your role, you can make them available in your role just >>> the same as if you had implemented them into your role itself. >>> >>> Perhaps can you describe an example of what you want to do? >> >> Well - that's what I was thinking, but: >> >> use strict; >> use warnings; >> >> { >> package Aa; >> use Exporter 'import'; >> our @EXPORT_OK = qw(foo); >> >> sub foo{ >> print "foo\n"; >> } >> } >> { >> package Bb; >> use Moose::Role; >> Aa->import( 'foo' ); >> >> sub baz { >> foo(shift); >> } >> >> sub bar { >> print "baaar\n"; >> } >> } >> { >> package Cc; >> use Moose; >> with 'Bb'; >> } >> >> my $c = Cc->new(); >> $c->bar; >> $c->baz; >> $c->foo; >> >> >> prints: >> >> baaar >> foo >> Can't locate object method "foo" via package "Cc" at a.pl line 37. >> >> So there is something missing, foo is not recognized as a method. > > No, because 'foo' is not a method, it is an imported function from another > package. Class::MOP checks the STASH of the CV to find out if it is a native > of that package and if not, it assumes it is an imported function and > therefore ignores it. > > It is a feature, not a bug :) > > - Stevan Additionally doing this is *really* nasty action-at-a-distance. Trying to explain what exactly is going on to someone who may or may not grasp the wonderful nuances that are Perl's package stashes and importation rules is not nearly as easy as explaining Attributes and Delegation. Think of the sanity of your downstream maintenance programmers. -Chris
Re: MooseX::NonMoose for Roles?
On Jan 28, 2011, at 4:06 PM, Zbigniew Lukasiak wrote: On Fri, Jan 28, 2011 at 9:35 PM, Karen Etheridge wrote: On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: Are there any sane options for building Moose::Roles out of Non Moose classes? Or maybe it is trivial? The thing about roles is they aren't instantiated, so you can't really do: package MyApp::Role::Foo; use base 'Some::Other::Class'; use Moose::Role; ...because there is no way to call up the inheritance tree to get at methods in Some::Other::Class. However, if you imported functions from that class into your role, you can make them available in your role just the same as if you had implemented them into your role itself. Perhaps can you describe an example of what you want to do? Well - that's what I was thinking, but: use strict; use warnings; { package Aa; use Exporter 'import'; our @EXPORT_OK = qw(foo); sub foo{ print "foo\n"; } } { package Bb; use Moose::Role; Aa->import( 'foo' ); sub baz { foo(shift); } sub bar { print "baaar\n"; } } { package Cc; use Moose; with 'Bb'; } my $c = Cc->new(); $c->bar; $c->baz; $c->foo; prints: baaar foo Can't locate object method "foo" via package "Cc" at a.pl line 37. So there is something missing, foo is not recognized as a method. No, because 'foo' is not a method, it is an imported function from another package. Class::MOP checks the STASH of the CV to find out if it is a native of that package and if not, it assumes it is an imported function and therefore ignores it. It is a feature, not a bug :) - Stevan
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 9:35 PM, Karen Etheridge wrote: > On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: >> Are there any sane options for building Moose::Roles out of Non Moose >> classes? >> >> Or maybe it is trivial? > > The thing about roles is they aren't instantiated, so you can't really do: > > package MyApp::Role::Foo; > > use base 'Some::Other::Class'; > use Moose::Role; > > ...because there is no way to call up the inheritance tree to get at > methods in Some::Other::Class. However, if you imported functions from > that class into your role, you can make them available in your role just > the same as if you had implemented them into your role itself. > > Perhaps can you describe an example of what you want to do? Well - that's what I was thinking, but: use strict; use warnings; { package Aa; use Exporter 'import'; our @EXPORT_OK = qw(foo); sub foo{ print "foo\n"; } } { package Bb; use Moose::Role; Aa->import( 'foo' ); sub baz { foo(shift); } sub bar { print "baaar\n"; } } { package Cc; use Moose; with 'Bb'; } my $c = Cc->new(); $c->bar; $c->baz; $c->foo; prints: baaar foo Can't locate object method "foo" via package "Cc" at a.pl line 37. So there is something missing, foo is not recognized as a method. Z.
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 9:31 PM, Hans Dieter Pearcey wrote: > On Fri, 28 Jan 2011 21:29:04 +0100, Zbigniew Lukasiak > wrote: >> Are there any sane options for building Moose::Roles out of Non Moose >> classes? > > "building roles out of classes" is like "building tires out of cars". > > Maybe you actually want a role that has an attribute that holds an instance of > your non-moose class and delegates several methods to it. Thanks! To be more precise - let's say that I have two classes that normally would be used in a multiple-inheritance pattern just as if one of them was a Role, and that one is not really instantiated. I'll look at the delegation possibilities. Cheers, Z.
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 12:35:38PM -0800, Karen Etheridge wrote: > However, if you imported functions from > that class into your role, you can make them available in your role just > the same as if you had implemented them into your role itself. ..However that only works for functions, not anything else (like any state that would be stored in the class - due to it not being instantiated). Bottom line, do what Jesse and Hans said and use delegation instead :) -- "Everything has been thought of before, but the problem is to think of it again." - Johann von Goethe . ... . Karen Etheridge, ka...@etheridge.ca GCS C+++$ USL+++$ P+++$ w--- M++ http://etheridge.ca/ PS++ PE-- b++ DI e++ h(-)
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: > Are there any sane options for building Moose::Roles out of Non Moose classes? > > Or maybe it is trivial? The thing about roles is they aren't instantiated, so you can't really do: package MyApp::Role::Foo; use base 'Some::Other::Class'; use Moose::Role; ...because there is no way to call up the inheritance tree to get at methods in Some::Other::Class. However, if you imported functions from that class into your role, you can make them available in your role just the same as if you had implemented them into your role itself. Perhaps can you describe an example of what you want to do? -- "Historic continuity with the past is not a duty, it is only a necessity." - Oliver Wendell Holmes, Jr. . ... . Karen Etheridge, ka...@etheridge.ca GCS C+++$ USL+++$ P+++$ w--- M++ http://etheridge.ca/ PS++ PE-- b++ DI e++ h(-)
Re: MooseX::NonMoose for Roles?
On Fri, Jan 28, 2011 at 09:29:04PM +0100, Zbigniew Lukasiak wrote: > Are there any sane options for building Moose::Roles out of Non Moose classes? > > Or maybe it is trivial? You can't just turn a class into a role - that doesn't really make sense. What you can do is use delegation instead: package Foo; use Moose::Role; has thing => ( is => 'ro', isa => 'Some::Non::Moose::Class', default => sub { Some::Non::Moose::Class->new }, handles => ['non_moose_method_1', 'non_moose_method_2'], ); See Moose::Manual::Delegation for more details. -doy
Re: MooseX::NonMoose for Roles?
On Fri, 28 Jan 2011 21:29:04 +0100, Zbigniew Lukasiak wrote: > Are there any sane options for building Moose::Roles out of Non Moose classes? "building roles out of classes" is like "building tires out of cars". Maybe you actually want a role that has an attribute that holds an instance of your non-moose class and delegates several methods to it. hdp.