Skip to content

Commit

Permalink
Forked from MouseX::Foreign and modified for Moose
Browse files Browse the repository at this point in the history
  • Loading branch information
gfx committed Nov 26, 2010
1 parent 66393af commit 7afa82a
Show file tree
Hide file tree
Showing 27 changed files with 433 additions and 376 deletions.
6 changes: 3 additions & 3 deletions Makefile.PL
Expand Up @@ -2,9 +2,9 @@ use strict;
use warnings;
use inc::Module::Install;

all_from 'lib/MouseX/Foreign.pm';
all_from 'lib/MooseX/Foreign.pm';

requires 'Mouse' => 0.77;
requires 'Moose' => 0.77;

test_requires 'Test::More' => 0.88; # done_testing()
test_requires 'Test::Requires';
Expand All @@ -15,7 +15,7 @@ author_tests 'xt';
auto_set_repository() if -d '.git';

clean_files qw(
MouseX-Foreign-*
MooseX-Foreign-*
*.stackdump
cover_db
nytprof
Expand Down
29 changes: 15 additions & 14 deletions lib/MouseX/Foreign.pm → lib/MooseX/Foreign.pm
@@ -1,10 +1,11 @@
package MouseX::Foreign;
package MooseX::Foreign;
use 5.008_001;
use Mouse::Util; # turns on strict and warnings
use strict;
use warnings;

our $VERSION = '0.003';

use Mouse::Util::MetaRole;
use Moose::Util::MetaRole;
use Carp ();

sub import {
Expand All @@ -14,13 +15,13 @@ sub import {
if(!$caller->can('meta')){
Carp::croak(
"$caller does not have the meta method"
. " (did you use Mouse for $caller?)");
. " (did you use Moose for $caller?)");
}

Mouse::Util::MetaRole::apply_metaroles(
Moose::Util::MetaRole::apply_metaroles(
for => $caller,
class_metaroles => {
class => ['MouseX::Foreign::Meta::Role::Class'],
class => ['MooseX::Foreign::Meta::Role::Class'],
},
);

Expand All @@ -33,17 +34,17 @@ __END__
=head1 NAME
MouseX::Foreign - Extends non-Mouse classes as well as Mouse classes
MooseX::Foreign - Extends non-Moose classes as well as Moose classes
=head1 VERSION
This document describes MouseX::Foreign version 0.003.
This document describes MooseX::Foreign version 0.003.
=head1 SYNOPSIS
package MyInt;
use Mouse;
use MouseX::Foreign qw(Math::BigInt);
use Moose;
use MooseX::Foreign qw(Math::BigInt);
has name => (
is => 'ro',
Expand All @@ -53,8 +54,8 @@ This document describes MouseX::Foreign version 0.003.
=head1 DESCRIPTION
MouseX::Foreign provides an ability for Mouse classes to extend any classes,
including non-Mouse classes, including Moose classes.
MooseX::Foreign provides an ability for Moose classes to extend any classes,
including non-Moose classes, including Moose classes.
=head1 DEPENDENCIES
Expand All @@ -69,11 +70,11 @@ to cpan-RT.
=head1 ACKNOWLEDGEMENT
This is a Mouse port of MooseX::NonMoose, although the name is different.
This is a Moose port of MooseX::NonMoose, although the name is different.
=head1 SEE ALSO
L<Mouse>
L<Moose>
L<Moose>
Expand Down
118 changes: 118 additions & 0 deletions lib/MooseX/Foreign/Meta/Role/Class.pm
@@ -0,0 +1,118 @@
package MooseX::Foreign::Meta::Role::Class;
use warnings FATAL => 'all';
use Moose::Role;
use Moose::Util::MetaRole;

has 'foreign_superclass' => (
is => 'rw',
isa => 'ClassName',
);

sub find_foreign_superclass {
my($self) = @_;
foreach my $class($self->linearized_isa) {
my $meta = Class::MOP::get_metaclass_by_name($class);
next if !(defined $meta and $meta->can('foreign_superclass'));
my $fsc = $meta->foreign_superclass;
return $fsc if defined $fsc;
}
return undef;
}

around superclasses => sub {
my($next, $self, @args) = @_;

my @isa = $self->$next(@args);
foreach my $super(@args) {
next if $super->isa('Moose::Object');
if( $super->can('new') or $super->can('DESTROY') ) {
$self->inherit_from_foreign_class($super);
}
}
return @isa;
};

#before verify_superclass => sub {
# my($self, $super, $super_meta) = @_;
#
# if(defined($super_meta) && $super_meta->does(__PACKAGE__)) {
# $self->inherit_from_foreign_class($super);
# }
# return;
#};

sub inherit_from_foreign_class { # override
my($self, $foreign_super) = @_;
# Carp::carp('### ', $self->name, ' inherit from ', $foreign_super);
if(defined $self->find_foreign_superclass) {
$self->throw_error(
"Multiple inheritance"
. " from foreign classes ($foreign_super, "
. $self->find_foreign_superclass
. ") is forbidden");
}
my %traits;
if($foreign_super->can('new')) {
$traits{constructor} = ['MooseX::Foreign::Meta::Role::Method::Constructor'];
}
if($foreign_super->can('DESTROY')) {
$traits{destructor} = ['MooseX::Foreign::Meta::Role::Method::Destructor'];
}
if(%traits) {
$_[0] = $self = Moose::Util::MetaRole::apply_metaroles(
for => $self,
class_metaroles => \%traits,
);
$self->foreign_superclass($foreign_super);

# DON'T CREATE INSTANCES BEFORE CALLING make_immutable()
$self->add_method(
new => sub { # provided for compatibility
my $constructor = $self->constructor_class->new(
options => {},
metaclass => $self,
is_inline => 0,
package_name => $self->name,
name => 'new',
);
$constructor->execute(@_);
});
$self->add_method(
DESTROY => sub {
my $destructor = $self->destructor_class->new(
options => {},
metaclass => $self,
package_name => $self->name,
name => 'DESTROY',
);
return $destructor->execute(@_);
});
}
return;
}

around _immutable_options => sub {
my($next, $self, @args) = @_;
my %args = $self->$next(@args);
$args{replace_constructor}++;
$args{replace_destructor}++;
return %args;
};

no Moose::Role;
1;
__END__
=head1 NAME
MooseX::Foreign::Meta::Role::Class - The MooseX::Foreign meta class role
=head1 DESCRIPTION
This is the meta class role for MooseX::Foreign.
=head1 SEE ALSO
L<MooseX::Foreign>
=cut
52 changes: 52 additions & 0 deletions lib/MooseX/Foreign/Meta/Role/Method/Constructor.pm
@@ -0,0 +1,52 @@
package MooseX::Foreign::Meta::Role::Method::Constructor;
use Moose::Role;

around _generate_instance => sub {
my($next, $self, $var, $class_var) = @_;

my $meta = $self->associated_metaclass;

# The foreign superlcass must have the new method
my $foreign_buildargs = $meta->name->can('FOREIGNBUILDARGS');
my $foreign_superclass = $meta->find_foreign_superclass
or confess("Oops: no foreign class for " . $meta->name);

my $foreign_args = $foreign_buildargs
? qq{$class_var->FOREIGNBUILDARGS(\@_)}
: q{@_};
return <<CODE;
my $var = $class_var->${foreign_superclass}::new($foreign_args);
CODE
};

around _generate_BUILDALL => sub {
my($next, $self) = @_;
my $meta = $self->associated_metaclass;
my $foreign_superclass = $meta->find_foreign_superclass;
my $needs_buildall = !$foreign_superclass->can('BUILDALL');

if($needs_buildall) {
return $self->$next();
}
else {
return '';
}
};

no Moose::Role;
1;
__END__
=head1 NAME
MooseX::Foreign::Meta::Role::Method::Constructor - The MooseX::Foreign meta method constructor role
=head1 DESCRIPTION
This is the meta method constructor role for MooseX::Foreign.
=head1 SEE ALSO
L<MooseX::Foreign>
=cut
40 changes: 40 additions & 0 deletions lib/MooseX/Foreign/Meta/Role/Method/Destructor.pm
@@ -0,0 +1,40 @@
package MooseX::Foreign::Meta::Role::Method::Destructor;
use Moose::Role;

# ugly hack to inject the foreig superclass's DESTROY
around _compile_code => sub {
my($next, $self, %args) = @_;

my $meta = $self->associated_metaclass;
my $foreign_superclass = $meta->find_foreign_superclass
or confess("Oops: no foreign superclass for " . $meta->name);

# if the foreign superclass has DEMOLISHALL, it will be a Mouse class
if(!$foreign_superclass->can('DEMOLISHALL')){
$args{code} =~ s/\} \z/ \$self->${foreign_superclass}::DESTROY() \}/xms;
}

return $self->$next(%args);
};

no Moose::Role;
1;
__END__
=head1 NAME
MooseX::Foreign::Meta::Role::Method::Destructor - The MooseX::Foreign meta method destructor role
=head1 VERSION
This document describes MooseX::Foreign version 0.003.
=head1 DESCRIPTION
This is the meta method destructor role for MooseX::Foreign.
=head1 SEE ALSO
L<MooseX::Foreign>
=cut
74 changes: 0 additions & 74 deletions lib/MouseX/Foreign/Meta/Role/Class.pm

This file was deleted.

0 comments on commit 7afa82a

Please sign in to comment.