I still struggle to find an imaginable use case.
strict isn't an object class.
Also, how would you specify the import arguments for a non-Moose class inherited via parent or base?
Here's what I've played with:
My/Parent.pm
package My::Parent;
use warnings;
use strict;
sub import {
my $name = { short => 'frob',
long => 'frobnicate'
}->{ $_[1] };
no strict 'refs';
*{$name} = *_frobnicate;
}
sub new { bless $_[1], $_[0] }
sub _frobnicate { $_[0]{a} + $_[0]{b} }
__PACKAGE__
Plus a test to show how it works:
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 1;
use My::Parent 'long';
my $p = 'My::Parent'->new( { a => 2, b => 3 } );
is $p->frobnicate, 5, 'frobnicates';
Inheriting via parent is possible, just note that the import method would be inherited, but you can override it and call the SUPER class's method:
My/SimpleChild.pm
package My::SimpleChild;
use warnings;
use strict;
use parent 'My::Parent';
sub import {
shift->SUPER::import('short');
}
__PACKAGE__
And it works:
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 1;
use My::SimpleChild;
my $s = 'My::SimpleChild'->new({ a => 2, b => 3 });
is $s->frob, 5, 'frobs';
In fact, you can use the same trick in Moose. I just added MooseX::NonMoose that handles inheriting from non-Moose classes correctly, and defined the a and b as proper attributes. For it to work, I needed to specify FOREIGNBUILDARGS so I can call the constructor without a hash reference:
My/MooseChild.pm
package My::MooseChild;
use Moose;
use MooseX::NonMoose;
extends 'My::Parent';
has a => (is => 'ro');
has b => (is => 'ro');
sub import { shift->SUPER::import('short') }
sub FOREIGNBUILDARGS {
my ($class, %args) = @_; \%args
}
no Moose;
__PACKAGE__->meta->make_immutable
And again, it works.
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 1;
use My::MooseChild;
my $m = 'My::MooseChild'->new(a => 2, b => 3);
is $m->frob, 5, 'frobs';
I'm not sure I'd go that way, though. I remember some monks preferred delegation over inheritance, and we can use it here, too:
My/DelegChild.pm
package My::DelegChild;
use Moose;
use My::Parent 'short';
has a => (is => 'ro');
has b => (is => 'ro');
has _parent => (is => 'ro',
lazy => 1,
default => sub { my ($self) = @_;
'My::Parent'->new({ a => $self->a,
b => $self->b });
},
handles => ['frob']);
no Moose;
__PACKAGE__->meta->make_immutable
#!/usr/bin/perl
use warnings;
use strict;
use Test::More tests => 1;
use My::DelegChild;
my $ch = 'My::DelegChild'->new(a => 2, b => 3);
is $ch->frob, 5, 'frobs';
It can all get very fragile and weird, because the import method changes the global state (and imagine what would happen if the parent's import method used state $name instead of my). It might be impossible to have two classes, each using different import parameters of the base class.
($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord
}map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.