Skip to content

Commit

Permalink
Factor out overload mangling into a role.
Browse files Browse the repository at this point in the history
  • Loading branch information
rafl committed Jul 30, 2009
1 parent fd2a78c commit e4ec444
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 42 deletions.
51 changes: 51 additions & 0 deletions lib/MooseX/Role/WithOverloading/Meta/Role/Application.pm
@@ -0,0 +1,51 @@
package MooseX::Role::WithOverloading::Meta::Role::Application;

use Moose::Role;
use overload ();
use MooseX::Types::Moose qw/ArrayRef Str/;
use namespace::autoclean;

has overload_ops => (
is => 'ro',
isa => ArrayRef[Str],
builder => '_build_overload_ops',
);

sub _build_overload_ops {
return [map { split /\s+/ } values %overload::ops];
}

after apply_methods => sub {
my ($self, $role, $other) = @_;
return unless overload::Overloaded($role->name);

$other->add_package_symbol('&()' => $role->get_package_symbol('&()'));
$other->add_package_symbol('$()' => $role->get_package_symbol('$()'))
if $role->has_package_symbol('$()');
# TODO: figure out why the mop variant doesn't work
# $other->namespace->{OVERLOAD}->{dummy}++;
{ no strict 'refs'; ${ $other->name . '::OVERLOAD' }{dummy}++; }

for my $op (@{ $self->overload_ops }) {
my $code_sym = '&(' . $op;

next if overload::Method($other->name, $op);
next unless $role->has_package_symbol($code_sym);

my $meth = $role->get_package_symbol($code_sym);
next unless $meth;

if ($meth == \&overload::nil) {
my $scalar_sym = qq{\$($op};
$other->add_package_symbol($code_sym => $meth);
$other->add_package_symbol(
$scalar_sym => ${ $role->get_package_symbol($scalar_sym) },
);
}
else {
$other->add_package_symbol(qq{&($op} => $meth);
}
}
};

1;
43 changes: 1 addition & 42 deletions lib/MooseX/Role/WithOverloading/Meta/Role/Application/ToClass.pm
@@ -1,49 +1,8 @@
package MooseX::Role::WithOverloading::Meta::Role::Application::ToClass;

use Moose::Role;
use overload ();
use MooseX::Types::Moose qw/ArrayRef Str/;
use namespace::autoclean;

has overload_ops => (
is => 'ro',
isa => ArrayRef[Str],
builder => '_build_overload_ops',
);

sub _build_overload_ops {
return [map { split /\s+/ } values %overload::ops];
}

after apply_methods => sub {
my ($self, $role, $class) = @_;
return unless overload::Overloaded($role->name);

$class->add_method('()' => $role->get_package_symbol('&()'));
$class->add_package_symbol('$()' => $role->get_package_symbol('$()'))
if $role->has_package_symbol('$()');
$class->namespace->{OVERLOAD}->{dummy}++;

for my $op (@{ $self->overload_ops }) {
my $code_sym = '&(' . $op;

next if $class->has_package_symbol($code_sym);
next unless $role->has_package_symbol($code_sym);

my $meth = $role->get_package_symbol($code_sym);
next unless $meth;

if ($meth == \&overload::nil) {
my $scalar_sym = qq{\$($op};
$class->add_package_symbol($code_sym => $meth);
$class->add_package_symbol(
$scalar_sym => ${ $role->get_package_symbol($scalar_sym) },
);
}
else {
$class->add_method(qq{($op} => $meth);
}
}
};
with 'MooseX::Role::WithOverloading::Meta::Role::Application';

1;

0 comments on commit e4ec444

Please sign in to comment.