1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
package MooseX::ABC;
use Moose ();
use Moose::Exporter;
# ABSTRACT: abstract base classes for Moose
=head1 SYNOPSIS
package Shape;
use Moose;
use MooseX::ABC;
requires 'draw';
package Circle;
use Moose;
extends 'Shape';
sub draw {
# stuff
}
my $shape = Shape->new; # dies
my $circle = Circle->new; # succeeds
package Square;
use Moose;
extends 'Shape'; # dies, since draw is unimplemented
=head1 DESCRIPTION
This module adds basic abstract base class functionality to Moose. Doing C<use
MooseX::ABC> turns the using class into an abstract class - it cannot be
instantiated. It also allows you to mark certain methods in the class as
L</required>, meaning that if a class inherits from this class without
implementing that method, it will die at compile time. Abstract subclasses are
exempt from this, however - if you extend a class with another class which uses
C<MooseX::ABC>, it will not be required to implement every required method (and
it can also add more required methods of its own). Only concrete classes
(classes which do not use C<MooseX::ABC>) are required to implement all of
their ancestors' required methods.
=cut
=func requires METHOD_NAMES
Takes a list of methods that classes inheriting from this one must implement.
If a class inherits from this class without implementing each method listed
here, an error will be thrown when compiling the class.
=cut
sub requires {
shift->add_required_method(@_);
}
my ($import, $unimport, $init_meta) = Moose::Exporter->build_import_methods(
with_meta => [qw(requires)],
install => [qw(import unimport)],
class_metaroles => {
class => ['MooseX::ABC::Trait::Class'],
},
base_class_roles => ['MooseX::ABC::Role::Object'],
);
sub init_meta {
my ($package, %options) = @_;
Carp::confess("Can't make a role into an abstract base class")
if Class::MOP::class_of($options{for_class})->isa('Moose::Meta::Role');
my $ret = $init_meta->(@_);
Class::MOP::class_of($options{for_class})->is_abstract(1);
return $ret;
}
=head1 SEE ALSO
L<Moose>
L<Moose::Role>
=begin Pod::Coverage
init_meta
=end Pod::Coverage
=cut
1;
|