Created
September 8, 2011 18:49
-
-
Save draegtun/1204277 to your computer and use it in GitHub Desktop.
One Base Class to Rule Them All (in Perl)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package MooseBase; | |
use Moose; | |
use Class::MOP; | |
# One Base Class to Rule Them All! | |
# | |
# see: https://www.destroyallsoftware.com/blog/2011/one-base-class-to-rule-them-all | |
# https://github.com/garybernhardt/base/blob/master/lib/base.rb | |
# http://news.ycombinator.com/item?id=2963525 | |
has anon_class => ( | |
is => 'ro', | |
isa => 'Class::MOP::Class', | |
default => sub { Class::MOP::Class->create_anon_class } | |
); | |
sub BUILD { | |
my @classes = do { | |
# get all defined (Moose) classes | |
my @universe = grep { $_ ne __PACKAGE__ } Moose::Object->meta->subclasses; | |
# get MooseBase subclasses because we don't want to look in these! | |
my @subclasses = __PACKAGE__->meta->direct_subclasses; | |
# Universe minus MooseBase derived classes | |
grep { my $class = $_; grep { $_ ne $class } @subclasses } @universe; | |
}; | |
# make this objects anon_class parents all the other Moose classes! | |
shift->anon_class->superclasses( @classes ); | |
} | |
sub AUTOLOAD { | |
my $self = shift; | |
my ($method_name) = our $AUTOLOAD =~ m/.*::(.*)/; | |
if ($self->anon_class->find_method_by_name( $method_name )) { | |
# only going to use first method it finds in object dispatch | |
my $instance = $self->anon_class->new_object; | |
$instance->$method_name( @_ ); | |
return $instance; # or $self ?? | |
} | |
else { die "No method found in meta!" } | |
} | |
no Moose; | |
1; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env perl | |
use 5.014; | |
use warnings; | |
{ | |
package Foo; | |
use Moose; | |
sub bar { say "bar" } | |
} | |
{ | |
package Baz; | |
use Moose; | |
extends 'Foo'; | |
has greeting => (is => 'ro', isa => 'Str', default => 'Hello' ); | |
sub baz { | |
my ($self, $text) = @_; | |
say $self->greeting, ' ', uc $text; | |
} | |
} | |
{ | |
package Cantaloupe; | |
use Moose; | |
extends "MooseBase"; | |
} | |
my $x = Cantaloupe->new; | |
say join ":", $x->anon_class->get_all_method_names; | |
$x->baz("there"); # from Baz | |
$x->bar; # from Foo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment