File Coverage

blib/lib/mop/method.pm
Criterion Covered Total %
statement 62 63 98.4
branch 4 6 66.6
condition 3 6 50.0
subroutine 16 16 100.0
pod 7 7 100.0
total 92 98 93.8


line stmt bran cond sub pod time code
1             package mop::method;
2              
3 143     143   1797 use v5.16;
  143         455  
  143         5436  
4 143     143   761 use warnings;
  143         261  
  143         4816  
5              
6 143     143   828 use Scalar::Util qw[ weaken ];
  143         262  
  143         9146  
7 143     143   949 use mop::internals::util;
  143         328  
  143         7472  
8              
9             our $VERSION = '0.03';
10             our $AUTHORITY = 'cpan:STEVAN';
11              
12 143     143   834 use parent 'mop::object', 'mop::internals::observable';
  143         289  
  143         1079  
13              
14             mop::internals::util::init_attribute_storage(my %name);
15             mop::internals::util::init_attribute_storage(my %body);
16             mop::internals::util::init_attribute_storage(my %associated_meta);
17             mop::internals::util::init_attribute_storage(my %original_id);
18              
19 58897   50 58897 1 62063 sub name { ${ $name{ $_[0] } // \undef } }
  58897         338942  
20 13773   50 13773 1 20482 sub body { ${ $body{ $_[0] } // \undef } }
  13773         59570  
21 23   50 23 1 53 sub associated_meta { ${ $associated_meta{ $_[0] } // \undef } }
  23         281  
22              
23             sub set_associated_meta {
24 16911     16911 1 26290 my ($self, $meta) = @_;
25 16911         55513 $associated_meta{ $self } = \$meta;
26 16911         23714 weaken(${ $associated_meta{ $self } });
  16911         77836  
27             }
28              
29             # temporary, for bootstrapping
30             sub new {
31 114     114   134 my $class = shift;
32 114         296 my %args = @_;
33 114         300 my $self = $class->SUPER::new;
34 114         383 $name{ $self } = \($args{'name'});
35 114         291 $body{ $self } = \($args{'body'});
36             # NOTE:
37             # keep track of the original ID here
38             # so that we can still detect method
39             # conflicts in roles even after something
40             # has been cloned
41             # - SL
42 114         250 $original_id{ $self } = \(mop::id($self));
43              
44 114         425 $self;
45             }
46              
47             # temporary, for bootstrapping
48             sub clone {
49 43     43   45 my $self = shift;
50 43         76 return ref($self)->new(name => $self->name, body => $self->body);
51             }
52              
53             sub execute {
54 767     767 1 1581 my ($self, $invocant, $args) = @_;
55              
56 767         2816 $self->fire('before:EXECUTE' => $invocant, $args);
57              
58 767         973 my @result;
59 767         1122 my $wantarray = wantarray;
60 767 50       2858 if ( $wantarray ) {
    100          
61 0         0 @result = $self->body->( $invocant, @$args );
62             } elsif ( defined $wantarray ) {
63 21         104 $result[0] = $self->body->( $invocant, @$args );
64             } else {
65 746         3001 $self->body->( $invocant, @$args );
66             }
67              
68 761         5031 $self->fire('after:EXECUTE' => $invocant, $args, \@result);
69              
70 761 50       5164 return $wantarray ? @result : $result[0];
71             }
72              
73 11     11 1 18 sub conflicts_with { ${ $original_id{ $_[0] } } ne ${ $original_id{ $_[1] } } }
  11         33  
  11         58  
74              
75 1316     1316 1 1338 sub locally_defined { ${ $original_id{ $_[0] } } eq mop::id( $_[0] ) }
  1316         7121  
76              
77             sub __INIT_METACLASS__ {
78 143     143   863 my $METACLASS = mop::class->new(
79             name => 'mop::method',
80             version => $VERSION,
81             authority => $AUTHORITY,
82             superclass => 'mop::object',
83             );
84              
85 143         759 $METACLASS->add_attribute(mop::attribute->new(
86             name => '$!name',
87             storage => \%name,
88             ));
89 143         681 $METACLASS->add_attribute(mop::attribute->new(
90             name => '$!body',
91             storage => \%body,
92             ));
93 143         822 $METACLASS->add_attribute(mop::attribute->new(
94             name => '$!associated_meta',
95             storage => \%associated_meta,
96             ));
97             $METACLASS->add_attribute(mop::attribute->new(
98             name => '$!original_id',
99             storage => \%original_id,
100 537     537   1626 default => sub { mop::id($_) },
101 143         1148 ));
102              
103 143         721 $METACLASS->add_method( mop::method->new( name => 'name', body => \&name ) );
104              
105 143         700 $METACLASS->add_method( mop::method->new( name => 'body', body => \&body ) );
106 143         719 $METACLASS->add_method( mop::method->new( name => 'execute', body => \&execute ) );
107              
108 143         653 $METACLASS->add_method( mop::method->new( name => 'associated_meta', body => \&associated_meta ) );
109 143         675 $METACLASS->add_method( mop::method->new( name => 'set_associated_meta', body => \&set_associated_meta ) );
110              
111 143         674 $METACLASS->add_method( mop::method->new( name => 'conflicts_with', body => \&conflicts_with ) );
112 143         830 $METACLASS->add_method( mop::method->new( name => 'locally_defined', body => \&locally_defined ) );
113              
114 143         1768 $METACLASS;
115             }
116              
117             1;
118              
119             __END__