File Coverage

blib/lib/Hades/Realm/OO.pm
Criterion Covered Total %
statement 241 384 62.7
branch 158 318 49.6
condition 115 187 61.5
subroutine 39 51 76.4
pod 38 38 100.0
total 591 978 60.4


line stmt bran cond sub pod time code
1             package Hades::Realm::OO;
2 2     2   227320 use strict;
  2         5  
  2         90  
3 2     2   8 use warnings;
  2         4  
  2         98  
4 2     2   917 use Hades::Myths { as_keywords => 1 };
  2         22561  
  2         17  
5 2     2   7429 use base qw/Hades/;
  2         6  
  2         1496  
6             our $VERSION = 0.08;
7              
8             sub new {
9 56 100   56 1 322147 my ( $cls, %args ) = ( shift(), scalar @_ == 1 ? %{ $_[0] } : @_ );
  55         174  
10 56         196 my $self = $cls->SUPER::new(%args);
11 56         584 my %accessors = ( is_role => {}, current_class => {}, meta => {}, );
12 56         171 for my $accessor ( keys %accessors ) {
13             my $param
14             = defined $args{$accessor}
15             ? $args{$accessor}
16 154 100       261 : $accessors{$accessor}->{default};
17             my $value
18             = $self->$accessor( $accessors{$accessor}->{builder}
19 154 50       385 ? $accessors{$accessor}->{builder}->( $self, $param )
20             : $param );
21 138 50 33     361 unless ( !$accessors{$accessor}->{required} || defined $value ) {
22 0         0 die "$accessor accessor is required";
23             }
24             }
25 40         240 return $self;
26             }
27              
28             sub current_class {
29 55     55 1 1296 my ( $self, $value ) = @_;
30 55 100       104 if ( defined $value ) {
31 14 100       18 if ( ref $value ) {
32 4         41 die qq{Str: invalid value $value for accessor current_class};
33             }
34 10         21 $self->{current_class} = $value;
35             }
36 51         93 return $self->{current_class};
37             }
38              
39             sub meta {
40 69     69 1 6843 my ( $self, $value ) = @_;
41 69 100       150 if ( defined $value ) {
42 28 100 100     76 if ( ( ref($value) || "" ) ne "HASH" ) {
43 4         38 die
44             qq{Map[Str, Dict[types => HashRef, attributes => HashRef]]: invalid value $value for accessor meta};
45             }
46 24         24 for my $key ( keys %{$value} ) {
  24         50  
47 24         35 my $val = $value->{$key};
48 24 50       55 if ( ref $key ) {
49 0         0 die
50             qq{Map[Str, Dict[types => HashRef, attributes => HashRef]]: invalid value $key for accessor meta expected Str};
51             }
52 24 100 100     60 if ( ( ref($val) || "" ) ne "HASH" ) {
53 6 100       10 $val = defined $val ? $val : 'undef';
54 6         65 die
55             qq{Map[Str, Dict[types => HashRef, attributes => HashRef]]: invalid value $val for accessor meta expected Dict[types=>HashRef,attributes=>HashRef]};
56             }
57 18 100 100     51 if ( ( ref( $val->{types} ) || "" ) ne "HASH" ) {
58             $val->{types}
59 8 100       21 = defined $val->{types} ? $val->{types} : 'undef';
60 8         77 die
61             qq{Map[Str, Dict[types => HashRef, attributes => HashRef]]: invalid value $val->{types} for accessor meta expected Dict[types=>HashRef,attributes=>HashRef] expected HashRef for types};
62             }
63 10 100 100     33 if ( ( ref( $val->{attributes} ) || "" ) ne "HASH" ) {
64             $val->{attributes}
65             = defined $val->{attributes}
66             ? $val->{attributes}
67 6 100       15 : 'undef';
68 6         76 die
69             qq{Map[Str, Dict[types => HashRef, attributes => HashRef]]: invalid value $val->{attributes} for accessor meta expected Dict[types=>HashRef,attributes=>HashRef] expected HashRef for attributes};
70             }
71             }
72 4         8 $self->{meta} = $value;
73             }
74 45         94 return $self->{meta};
75             }
76              
77             sub is_role {
78 57     57 1 1257 my ( $self, $value ) = @_;
79 57 100       107 if ( defined $value ) {
80 15         22 my $ref = ref $value;
81 15 50 100     97 if ( ( $ref || 'SCALAR' ) ne 'SCALAR'
    100 66        
82             || ( $ref ? $$value : $value ) !~ m/^(1|0)$/ )
83             {
84 4         40 die qq{Bool: invalid value $value for accessor is_role};
85             }
86 11 50       24 $value = !!( $ref ? $$value : $value ) ? 1 : 0;
    50          
87 11         21 $self->{is_role} = $value;
88             }
89 53         117 return $self->{is_role};
90             }
91              
92             sub clear_is_role {
93 1     1 1 3 my ($self) = @_;
94 1         2 delete $self->{is_role};
95 1         4 return $self;
96             }
97              
98             sub module_generate {
99 2     2 1 619 my ( $self, $mg ) = @_;
100 2 50 100     26 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
101 2 50       5 $mg = defined $mg ? $mg : 'undef';
102 2         22 die
103             qq{Object: invalid value $mg for variable \$mg in method module_generate};
104             }
105              
106             $mg->keyword(
107             'function',
108 0     0   0 CODE => sub { $self->build_function(@_) },
109 0         0 KEYWORDS => $self->build_function_keywords,
110             POD_TITLE => 'FUNCTIONS',
111             POD_POD => 'Call $keyword function',
112             POD_EXAMPLE => "\$obj->\$keyword;\n\n\t\$obj->\$keyword(\$value)"
113             );
114             $mg->keyword(
115             'has',
116 0     0   0 CODE => sub { $self->build_has(@_) },
117 0         0 KEYWORDS => $self->build_has_keywords,
118             POD_TITLE => 'ATTRIBUTES',
119             POD_POD => 'Get or set $keyword',
120             POD_EXAMPLE => "\$obj->\$keyword;\n\n\t\$obj->\$keyword(\$value)"
121             );
122             $mg->keyword(
123             'extends',
124 0     0   0 CODE => sub { $self->build_extends(@_) },
125 0         0 KEYWORDS => $self->build_extends_keywords,
126             POD_TITLE => 'EXTENDS',
127             POD_POD => 'This class extends the following classes',
128             POD_EXAMPLE => "\$keyword"
129             );
130             $mg->keyword(
131             'with',
132 0     0   0 CODE => sub { $self->build_with(@_) },
133 0         0 KEYWORDS => $self->build_with_keywords,
134             POD_TITLE => 'WITH',
135             POD_POD => 'This class includes the following roles',
136             POD_EXAMPLE => "\$keyword"
137             );
138             $mg->keyword(
139             'requires',
140 0     0   0 CODE => sub { $self->build_requires(@_) },
141 0         0 KEYWORDS => $self->build_requires_keywords,
142             POD_TITLE => 'REQUIRES',
143             POD_POD => 'This class requires:',
144             POD_EXAMPLE => "\$keyword"
145             );
146             $mg->keyword(
147             'before',
148 0     0   0 CODE => sub { $self->build_before(@_) },
149 0         0 KEYWORDS => $self->build_before_keywords,
150             POD_TITLE => 'BEFORE',
151             POD_POD => 'Call $keyword method',
152             POD_EXAMPLE => "\$obj->\$keyword"
153             );
154             $mg->keyword(
155             'around',
156 0     0   0 CODE => sub { $self->build_around(@_) },
157 0         0 KEYWORDS => $self->build_around_keywords,
158             POD_TITLE => 'AROUND',
159             POD_POD => 'Call $keyword method',
160             POD_EXAMPLE => "\$obj->\$keyword"
161             );
162             $mg->keyword(
163             'after',
164 0     0   0 CODE => sub { $self->build_after(@_) },
165 0         0 KEYWORDS => $self->build_after_keywords,
166             POD_TITLE => 'AFTER',
167             POD_POD => 'Call $keyword method',
168             POD_EXAMPLE => "\$obj->\$keyword"
169             );
170              
171             }
172              
173             sub build_class_inheritance {
174 0     0 1 0 my ( $orig, $self, @params ) = ( 'SUPER::build_class_inheritance', @_ );
175              
176 0 0 0     0 if ( $params[-1] =~ m/^(role)$/i ) {
    0          
    0          
177 0         0 $self->is_role(1);
178 0         0 return $params[-2];
179             }
180             elsif ( $params[-1] =~ m/^(with|extends|parent|base)$/ ) {
181 0 0       0 return 'extends' if $1 =~ m/parent|base/;
182 0         0 return $params[-1];
183             }
184             elsif ( $params[-2] && $params[-2] =~ m/^(with|extends)$/ ) {
185 0         0 my ( $mg, $last, $ident ) = splice @params, -3;
186 0         0 $mg->$last($ident);
187 0         0 return $last;
188             }
189 0         0 my @res = $self->$orig(@params);
190 0 0       0 return wantarray ? @res : $res[0];
191             }
192              
193             sub build_new {
194 6     6 1 2755 my ( $self, $mg, $meta, $types ) = @_;
195 6 100 100     40 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
196 2 50       6 $mg = defined $mg ? $mg : 'undef';
197 2         17 die
198             qq{Object: invalid value $mg for variable \$mg in method build_new};
199             }
200 4 100 100     16 if ( ( ref($meta) || "" ) ne "HASH" ) {
201 2 50       5 $meta = defined $meta ? $meta : 'undef';
202 2         23 die
203             qq{HashRef: invalid value $meta for variable \$meta in method build_new};
204             }
205 2 50       6 $types = defined $types ? $types : {};
206 2 50 100     9 if ( ( ref($types) || "" ) ne "HASH" ) {
207 2 50       3 $types = defined $types ? $types : 'undef';
208 2         16 die
209             qq{HashRef: invalid value $types for variable \$types in method build_new};
210             }
211              
212 0         0 my %class = %Module::Generate::CLASS;
213 0         0 my %accessors = ();
214             map {
215 0         0 my $key = $_;
216             exists $meta->{$key}->{$_}
217 0         0 && do { $accessors{$key}->{$_} = $meta->{$key}->{$_} }
218 0   0     0 for ( @{ $self->build_has_keywords } );
  0         0  
219             } grep {
220             $self->unique_types( $meta->{$_}->{type}, $types )
221 0 0       0 if $meta->{$_}->{type};
222 0         0 $meta->{$_}->{meta} eq 'ACCESSOR';
223 0         0 } keys %{$meta};
  0         0  
224 0         0 my $class_meta = $self->meta;
225             $class_meta->{ $class{CURRENT}{NAME} } = {
226 0         0 types => $types,
227             attributes => \%accessors
228             };
229 0         0 $self->meta($class_meta);
230 0         0 $self->current_class( $class{CURRENT}{NAME} );
231 0         0 $class{CURRENT}{SUBS}{new}{NO_CODE} = 1;
232             $class{CURRENT}{SUBS}{new}{TEST}
233 0         0 = [ $self->build_tests( 'new', $meta, 'new', \%class ) ];
234              
235             }
236              
237             sub build_clearer {
238 0     0 1 0 my ( $orig, $self, @params ) = ( 'SUPER::build_clearer', @_ );
239 0         0 my @res = $self->$orig(@params);
240 0         0 $res[0]->no_code(1);
241              
242 0 0       0 return wantarray ? @res : $res[0];
243             }
244              
245             sub build_predicate {
246 0     0 1 0 my ( $orig, $self, @params ) = ( 'SUPER::build_predicate', @_ );
247 0         0 my @res = $self->$orig(@params);
248 0         0 $res[0]->no_code(1);
249              
250 0 0       0 return wantarray ? @res : $res[0];
251             }
252              
253             sub build_accessor_no_arguments {
254 6     6 1 3135 my ( $self, $mg, $token, $meta ) = @_;
255 6 100 100     42 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
256 2 50       7 $mg = defined $mg ? $mg : 'undef';
257 2         22 die
258             qq{Object: invalid value $mg for variable \$mg in method build_accessor_no_arguments};
259             }
260 4 100 100     23 if ( !defined($token) || ( ref($token) || "" ) ne "ARRAY" ) {
      66        
261 2 50       5 $token = defined $token ? $token : 'undef';
262 2         17 die
263             qq{ArrayRef: invalid value $token for variable \$token in method build_accessor_no_arguments};
264             }
265 2 50 100     11 if ( ( ref($meta) || "" ) ne "HASH" ) {
266 2 50       4 $meta = defined $meta ? $meta : 'undef';
267 2         17 die
268             qq{HashRef: invalid value $meta for variable \$meta in method build_accessor_no_arguments};
269             }
270              
271 0         0 $meta->{ $token->[0] }->{meta} = 'ACCESSOR';
272 0         0 $mg->has( $token->[0] );
273 0         0 return $meta;
274              
275             }
276              
277             sub build_accessor {
278 6     6 1 2853 my ( $self, $mg, $name, $meta ) = @_;
279 6 100 100     47 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
280 2 50       5 $mg = defined $mg ? $mg : 'undef';
281 2         17 die
282             qq{Object: invalid value $mg for variable \$mg in method build_accessor};
283             }
284 4 100 66     20 if ( !defined($name) || ref $name ) {
285 2 50       6 $name = defined $name ? $name : 'undef';
286 2         22 die
287             qq{Str: invalid value $name for variable \$name in method build_accessor};
288             }
289 2 50 100     8 if ( ( ref($meta) || "" ) ne "HASH" ) {
290 2 50       5 $meta = defined $meta ? $meta : 'undef';
291 2         18 die
292             qq{HashRef: invalid value $meta for variable \$meta in method build_accessor};
293             }
294              
295 0         0 $mg->has($name);
296             $meta->{$name}->{$_} and $mg->$_(
297             $self->build_code(
298             $mg,
299             $name,
300             $self->can("build_accessor_${_}")
301             ? $self->can("build_accessor_${_}")
302             ->( $self, $name, $meta->{$name}->{$_} )
303             : $meta->{$name}->{$_}
304             )
305 0 0 0     0 ) for ( @{ $self->build_has_keywords } );
  0         0  
306             $mg->isa(
307             $self->can("build_accessor_isa")
308             ? $self->can("build_accessor_isa")
309             ->( $self, $name, $meta->{$name}->{type}->[0] )
310             : $meta->{$name}->{type}->[0]
311 0 0       0 ) if !$meta->{$name}->{isa};
    0          
312 0         0 $mg->clear_tests->test( $self->build_tests( $name, $meta->{$name} ) );
313             $meta->{$name}->{$_}
314             && $mg->$_( $self->replace_pe_string( $meta->{$name}->{$_}, $name ) )
315 0   0     0 for qw/pod example/;
316              
317             }
318              
319             sub build_sub {
320 6     6 1 2859 my ( $self, $mg, $name, $meta ) = @_;
321 6 100 100     47 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
322 2 50       4 $mg = defined $mg ? $mg : 'undef';
323 2         36 die
324             qq{Object: invalid value $mg for variable \$mg in method build_sub};
325             }
326 4 100 66     19 if ( !defined($name) || ref $name ) {
327 2 50       4 $name = defined $name ? $name : 'undef';
328 2         20 die
329             qq{Str: invalid value $name for variable \$name in method build_sub};
330             }
331 2 50 100     9 if ( ( ref($meta) || "" ) ne "HASH" ) {
332 2 50       6 $meta = defined $meta ? $meta : 'undef';
333 2         38 die
334             qq{HashRef: invalid value $meta for variable \$meta in method build_sub};
335             }
336              
337 0 0 0     0 return $self->SUPER::build_sub( $mg, $name, $meta )
338             unless ( $self->can('has_function_keyword')
339             && $self->has_function_keyword );
340 0         0 my $code = $meta->{$name}->{code};
341 0         0 $self->debug_step( sprintf( debug_step_31, $name ), $meta->{$name} );
342 0         0 my ( $params, $subtype, $params_explanation ) = ( '', '', '' );
343 0 0       0 $subtype .= $self->build_private($name) if $meta->{$name}->{private};
344 0 0       0 if ( $meta->{$name}->{param} ) {
345 0         0 for my $param ( @{ $meta->{$name}->{param} } ) {
  0         0  
346 0 0       0 $params_explanation .= ', ' if $params_explanation;
347 0         0 $params .= ', ' . $param;
348 0         0 my $pm = $meta->{$name}->{params_map}->{$param};
349             $subtype .= qq|$param = defined $param ? $param : $pm->{default};|
350 0 0       0 if ( $pm->{default} );
351 0         0 $subtype .= $self->build_coerce( $name, $param, $pm->{coerce} );
352 0 0       0 if ( $pm->{type} ) {
353             my $error_message
354 0 0       0 = ( $pm->{type} !~ m/^(Optional|Any|Item)/
355             ? qq|$param = defined $param ? $param : 'undef';|
356             : q|| )
357             . qq|die qq{$pm->{type}: invalid value $param for variable \\$param in method $name};|;
358             $subtype .= $self->build_type(
359             $name,
360             $pm->{type},
361             $param,
362             $error_message,
363 0 0       0 ( $pm->{type} !~ m/^(Optional|Any|Item)/
364             ? qq|! defined($param) \|\||
365             : q||
366             )
367             );
368 0         0 $params_explanation .= qq|param $param to be a $pm->{type}|;
369             }
370             else {
371 0         0 $params_explanation
372             .= qq|param $param to be any value including undef|;
373             }
374             }
375             }
376 0         0 $meta->{$name}->{params_explanation} = $params_explanation;
377 0         0 $code = $self->build_code( $mg, $name,
378             $self->build_sub_code( $name, $params, $subtype, $code ) );
379 0         0 $params =~ s/^,\s*//;
380 0         0 my $example = qq|\$obj->$name($params)|;
381             $mg->function($name)->code($code)
382             ->pod(qq|call $name method. Expects $params_explanation.|)
383             ->example($example)
384 0         0 ->test( $self->build_tests( $name, $meta->{$name} ) );
385             $meta->{$name}->{$_}
386             && $mg->$_( $self->replace_pe_string( $meta->{$name}->{$_}, $name ) )
387 0   0     0 for qw/pod example/;
388              
389             }
390              
391             sub build_modify {
392 6     6 1 2736 my ( $self, $mg, $name, $meta ) = @_;
393 6 100 100     50 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
394 2 50       5 $mg = defined $mg ? $mg : 'undef';
395 2         17 die
396             qq{Object: invalid value $mg for variable \$mg in method build_modify};
397             }
398 4 100 66     48 if ( !defined($name) || ref $name ) {
399 2 50       5 $name = defined $name ? $name : 'undef';
400 2         19 die
401             qq{Str: invalid value $name for variable \$name in method build_modify};
402             }
403 2 50 100     9 if ( ( ref($meta) || "" ) ne "HASH" ) {
404 2 50       6 $meta = defined $meta ? $meta : 'undef';
405 2         16 die
406             qq{HashRef: invalid value $meta for variable \$meta in method build_modify};
407             }
408              
409             $meta->{$name}->{$_}
410             && $mg->$_($name)
411             ->code( $self->build_code( $mg, $name, delete $meta->{$name}->{$_} ) )
412             ->test( $self->build_tests( $name, $meta->{$name} ) )
413 0   0     0 for qw/before around after/;
414             $meta->{$name}->{$_}
415             && $mg->$_(
416             $self->replace_pe_string( delete $meta->{$name}->{$_}, $name ) )
417 0   0     0 for qw/pod example/;
418              
419             }
420              
421             sub after_class {
422 4     4 1 1698 my ( $self, $mg, $meta ) = @_;
423 4 100 100     30 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
424 2 50       5 $mg = defined $mg ? $mg : 'undef';
425 2         16 die
426             qq{Object: invalid value $mg for variable \$mg in method after_class};
427             }
428 2 50 100     8 if ( ( ref($meta) || "" ) ne "HASH" ) {
429 2 50       5 $meta = defined $meta ? $meta : 'undef';
430 2         16 die
431             qq{HashRef: invalid value $meta for variable \$meta in method after_class};
432             }
433              
434 0 0 0     0 $self->is_role && $self->clear_is_role
435             ? $self->build_as_role( $mg, $meta )
436             : $self->build_as_class( $mg, $meta );
437              
438             }
439              
440             sub unique_types {
441 3     3 1 1121 my ( $self, $type, $unique ) = @_;
442 3 50       11 if ( ref $type eq 'ARRAY' ) {
443 0 0       0 if ( scalar @{$type} ) {
  0         0  
444 0         0 $self->unique_types( $_, $unique ) for @{$type};
  0         0  
445             }
446 0         0 return;
447             }
448 3 100 66     11 if ( !defined($type) || ref $type ) {
449 1 50       4 $type = defined $type ? $type : 'undef';
450 1         10 die
451             qq{Str: invalid value $type for variable \$type in method unique_types};
452             }
453 2 50 100     22 if ( ( ref($unique) || "" ) ne "HASH" ) {
454 2 50       6 $unique = defined $unique ? $unique : 'undef';
455 2         17 die
456             qq{HashRef: invalid value $unique for variable \$unique in method unique_types};
457             }
458              
459 0 0 0     0 if ( $type =~ s/^([^\[ ]+)\[(.*)\]$/$2/ ) {
    0          
460 0         0 my ( $t, $v ) = ( $1, $2 );
461 0 0       0 $unique->{$t}++ if ( $t =~ m/^\w+$/ );
462 0         0 $v =~ s/,\s*\d+,\s*\d+$//g;
463 0         0 $self->unique_types( $v, $unique );
464             }
465             elsif ( $type =~ m/^\s*\w+\s*\=\>\s*/ || $type =~ m/^([^,]+),\s*(.*)$/ ) {
466 0         0 my @matches = split ',', $type;
467 0         0 while (@matches) {
468 0         0 my ($match) = ( shift @matches );
469 0 0 0     0 if ( @matches && $match =~ m/(Map|Tuple|ArrayRef|Dict)\[/ ) {
470             my $cb = sub {
471 0     0   0 my $copy = shift;
472 0         0 1 while ( $copy =~ s/\[[^\[\]]+\]//g );
473 0 0       0 return ( $copy =~ m/\[|\]/ ) ? 1 : 0;
474 0         0 };
475 0         0 1 while ( $cb->( $match .= ', ' . shift @matches ) );
476             }
477             my ( $k, $v )
478 0 0       0 = map { my $h = $_; $h =~ s/^\s*|\s*$//g; $h; }
  0         0  
  0         0  
  0         0  
479             $match =~ m/\s+\w*\s*\=\>/
480             ? split( '=>', $match, 2 )
481             : $match;
482 0   0     0 $self->unique_types( $v || $k, $unique );
483             }
484             }
485             else {
486 0         0 $unique->{$type}++;
487             }
488              
489             }
490              
491             sub build_as_class {
492 4     4 1 1749 my ( $self, $mg, $meta ) = @_;
493 4 100 100     47 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
494 2 50       5 $mg = defined $mg ? $mg : 'undef';
495 2         47 die
496             qq{Object: invalid value $mg for variable \$mg in method build_as_class};
497             }
498 2 50 100     10 if ( ( ref($meta) || "" ) ne "HASH" ) {
499 2 50       4 $meta = defined $meta ? $meta : 'undef';
500 2         17 die
501             qq{HashRef: invalid value $meta for variable \$meta in method build_as_class};
502             }
503 0         0 return ( $mg, $meta );
504             }
505              
506             sub build_as_role {
507 4     4 1 1834 my ( $self, $mg, $meta ) = @_;
508 4 100 100     29 if ( ( ref($mg) || "" ) =~ m/^(|HASH|ARRAY|SCALAR|CODE|GLOB)$/ ) {
509 2 50       5 $mg = defined $mg ? $mg : 'undef';
510 2         17 die
511             qq{Object: invalid value $mg for variable \$mg in method build_as_role};
512             }
513 2 50 100     11 if ( ( ref($meta) || "" ) ne "HASH" ) {
514 2 50       4 $meta = defined $meta ? $meta : 'undef';
515 2         17 die
516             qq{HashRef: invalid value $meta for variable \$meta in method build_as_role};
517             }
518 0         0 return ( $mg, $meta );
519             }
520              
521             sub build_has_keywords {
522 2     2 1 639 my ( $self, $keywords ) = @_;
523 2 50       7 $keywords
524             = defined $keywords
525             ? $keywords
526             : [
527             qw/is isa required default clearer coerce predicate trigger private builder/
528             ];
529 2 50 100     17 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
530 2 50       4 $keywords = defined $keywords ? $keywords : 'undef';
531 2         21 die
532             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_has_keywords};
533             }
534 0         0 return $keywords;
535             }
536              
537             sub build_has {
538 2     2 1 613 my ( $self, $meta ) = @_;
539 2 50 100     11 if ( ( ref($meta) || "" ) ne "HASH" ) {
540 2 50       4 $meta = defined $meta ? $meta : 'undef';
541 2         16 die
542             qq{HashRef: invalid value $meta for variable \$meta in method build_has};
543             }
544              
545 0         0 my $name = $meta->{has};
546 0         0 my $private = $self->SUPER::build_private( $name, $meta->{private} );
547             my $type = $self->SUPER::build_coerce( $name, '$value', $meta->{coerce} )
548 0         0 . $self->build_type( $name, $meta->{type}[0] );
549             my $trigger
550 0         0 = $self->SUPER::build_trigger( $name, '$value', $meta->{trigger} );
551 0         0 return qq|{
552             my ( \$self, \$value ) = \@_; $private
553             if ( defined \$value ) { $type
554             $self->{$name} = \$value; $trigger
555             }
556             return $self->{$name};
557             }|;
558              
559             }
560              
561             sub build_function_keywords {
562 2     2 1 552 my ( $self, $keywords ) = @_;
563 2 50       6 $keywords = defined $keywords ? $keywords : [''];
564 2 50 100     15 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
565 2 50       3 $keywords = defined $keywords ? $keywords : 'undef';
566 2         17 die
567             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_function_keywords};
568             }
569 0         0 return $keywords;
570             }
571              
572             sub build_function {
573 2     2 1 550 my ( $self, $meta ) = @_;
574 2 50 100     12 if ( ( ref($meta) || "" ) ne "HASH" ) {
575 2 50       4 $meta = defined $meta ? $meta : 'undef';
576 2         16 die
577             qq{HashRef: invalid value $meta for variable \$meta in method build_function};
578             }
579              
580 0         0 return qq(function $meta->{function} => sub $meta->{CODE};);
581              
582             }
583              
584             sub build_extends_keywords {
585 2     2 1 641 my ( $self, $keywords ) = @_;
586 2 50       5 $keywords = defined $keywords ? $keywords : [];
587 2 50 100     14 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
588 2 50       5 $keywords = defined $keywords ? $keywords : 'undef';
589 2         16 die
590             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_extends_keywords};
591             }
592 0         0 return $keywords;
593             }
594              
595             sub build_extends {
596 2     2 1 614 my ( $self, $meta ) = @_;
597 2 50 100     12 if ( ( ref($meta) || "" ) ne "HASH" ) {
598 2 50       4 $meta = defined $meta ? $meta : 'undef';
599 2         15 die
600             qq{HashRef: invalid value $meta for variable \$meta in method build_extends};
601             }
602              
603             $meta->{extends} = '"' . $meta->{extends} . '"'
604 0 0       0 if $meta->{extends} !~ m/^["'q]/;
605 0         0 return qq(extends $meta->{extends};);
606              
607             }
608              
609             sub build_with_keywords {
610 2     2 1 539 my ( $self, $keywords ) = @_;
611 2 50       6 $keywords = defined $keywords ? $keywords : [];
612 2 50 100     14 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
613 2 50       10 $keywords = defined $keywords ? $keywords : 'undef';
614 2         16 die
615             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_with_keywords};
616             }
617 0         0 return $keywords;
618             }
619              
620             sub build_with {
621 2     2 1 557 my ( $self, $meta ) = @_;
622 2 50 100     24 if ( ( ref($meta) || "" ) ne "HASH" ) {
623 2 50       5 $meta = defined $meta ? $meta : 'undef';
624 2         18 die
625             qq{HashRef: invalid value $meta for variable \$meta in method build_with};
626             }
627              
628 0 0       0 $meta->{with} = '"' . $meta->{with} . '"' if $meta->{with} !~ m/^["'q]/;
629 0         0 return qq(with $meta->{with};);
630              
631             }
632              
633             sub build_requires_keywords {
634 2     2 1 552 my ( $self, $keywords ) = @_;
635 2 50       5 $keywords = defined $keywords ? $keywords : [];
636 2 50 100     14 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
637 2 50       3 $keywords = defined $keywords ? $keywords : 'undef';
638 2         17 die
639             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_requires_keywords};
640             }
641 0         0 return $keywords;
642             }
643              
644             sub build_requires {
645 2     2 1 571 my ( $self, $meta ) = @_;
646 2 50 100     9 if ( ( ref($meta) || "" ) ne "HASH" ) {
647 2 50       4 $meta = defined $meta ? $meta : 'undef';
648 2         15 die
649             qq{HashRef: invalid value $meta for variable \$meta in method build_requires};
650             }
651              
652             $meta->{requires} = '"' . $meta->{requires} . '"'
653 0 0       0 if $meta->{requires} !~ m/^["'q]/;
654 0         0 return qq(requires $meta->{requires};);
655              
656             }
657              
658             sub build_before_keywords {
659 2     2 1 566 my ( $self, $keywords ) = @_;
660 2 50       5 $keywords = defined $keywords ? $keywords : [];
661 2 50 100     14 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
662 2 50       3 $keywords = defined $keywords ? $keywords : 'undef';
663 2         16 die
664             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_before_keywords};
665             }
666 0         0 return $keywords;
667             }
668              
669             sub build_before {
670 2     2 1 646 my ( $self, $meta ) = @_;
671 2 50 100     11 if ( ( ref($meta) || "" ) ne "HASH" ) {
672 2 50       5 $meta = defined $meta ? $meta : 'undef';
673 2         16 die
674             qq{HashRef: invalid value $meta for variable \$meta in method build_before};
675             }
676              
677             return
678 0         0 qq(before $meta->{before} => sub { my (\$orig, \$self, \@params) = \@_; $meta->{CODE} };);
679              
680             }
681              
682             sub build_around_keywords {
683 2     2 1 933 my ( $self, $keywords ) = @_;
684 2 50       6 $keywords = defined $keywords ? $keywords : [];
685 2 50 100     18 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
686 2 50       4 $keywords = defined $keywords ? $keywords : 'undef';
687 2         19 die
688             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_around_keywords};
689             }
690 0         0 return $keywords;
691             }
692              
693             sub build_around {
694 2     2 1 987 my ( $self, $meta ) = @_;
695 2 50 100     16 if ( ( ref($meta) || "" ) ne "HASH" ) {
696 2 50       7 $meta = defined $meta ? $meta : 'undef';
697 2         24 die
698             qq{HashRef: invalid value $meta for variable \$meta in method build_around};
699             }
700              
701             return
702 0         0 qq(around $meta->{around} => sub { my (\$orig, \$self, \@params) = \@_; $meta->{CODE} };);
703              
704             }
705              
706             sub build_after_keywords {
707 2     2 1 976 my ( $self, $keywords ) = @_;
708 2 50       7 $keywords = defined $keywords ? $keywords : [];
709 2 50 100     20 if ( !defined($keywords) || ( ref($keywords) || "" ) ne "ARRAY" ) {
      33        
710 2 50       7 $keywords = defined $keywords ? $keywords : 'undef';
711 2         24 die
712             qq{ArrayRef: invalid value $keywords for variable \$keywords in method build_after_keywords};
713             }
714 0         0 return $keywords;
715             }
716              
717             sub build_after {
718 2     2 1 959 my ( $self, $meta ) = @_;
719 2 50 100     15 if ( ( ref($meta) || "" ) ne "HASH" ) {
720 2 50       7 $meta = defined $meta ? $meta : 'undef';
721 2         24 die
722             qq{HashRef: invalid value $meta for variable \$meta in method build_after};
723             }
724              
725             return
726 0         0 qq(after $meta->{after} => sub { my (\$orig, \@params) = \@_; $meta->{CODE} };);
727              
728             }
729              
730             sub build_accessor_builder {
731 4     4 1 2973 my ( $self, $name, $content ) = @_;
732 4 100 66     29 if ( !defined($name) || ref $name ) {
733 2 50       7 $name = defined $name ? $name : 'undef';
734 2         27 die
735             qq{Str: invalid value $name for variable \$name in method build_accessor_builder};
736             }
737 2 50 33     40 if ( !defined($content) || ref $content ) {
738 2 50       8 $content = defined $content ? $content : 'undef';
739 2         26 die
740             qq{Str: invalid value $content for variable \$content in method build_accessor_builder};
741             }
742              
743             return (
744 0 0       0 $content =~ m/^(\w+|1)$/
745             ? qq|$content|
746             : qq|sub {
747             my (\$self, \$value) = \@_;
748             $content
749             return \$value;
750             }|
751             );
752              
753             }
754              
755             sub build_accessor_coerce {
756 4     4 1 2694 my ( $self, $name, $content ) = @_;
757 4 100 66     28 if ( !defined($name) || ref $name ) {
758 2 50       6 $name = defined $name ? $name : 'undef';
759 2         24 die
760             qq{Str: invalid value $name for variable \$name in method build_accessor_coerce};
761             }
762 2 50 33     11 if ( !defined($content) || ref $content ) {
763 2 50       8 $content = defined $content ? $content : 'undef';
764 2         23 die
765             qq{Str: invalid value $content for variable \$content in method build_accessor_coerce};
766             }
767              
768 0 0       0 return q|sub { my ($value) = @_;|
769             . (
770             $content =~ m/^\w+$/
771             ? qq|\$value = __PACKAGE__->$content(\$value);|
772             : $content
773             ) . q|return $value; }|;
774              
775             }
776              
777             sub build_accessor_trigger {
778 4     4 1 2689 my ( $self, $name, $content ) = @_;
779 4 100 66     27 if ( !defined($name) || ref $name ) {
780 2 50       8 $name = defined $name ? $name : 'undef';
781 2         24 die
782             qq{Str: invalid value $name for variable \$name in method build_accessor_trigger};
783             }
784 2 50 33     13 if ( !defined($content) || ref $content ) {
785 2 50       7 $content = defined $content ? $content : 'undef';
786 2         24 die
787             qq{Str: invalid value $content for variable \$content in method build_accessor_trigger};
788             }
789              
790 0 0       0 return q|sub { my ($self, $value) = @_;|
791             . (
792             $content =~ m/^\w+$/
793             ? qq|\$value = \$self->$content(\$value);|
794             : $content
795             ) . q|return $value; }|;
796              
797             }
798              
799             sub build_accessor_default {
800 4     4 1 2651 my ( $self, $name, $content ) = @_;
801 4 100 66     27 if ( !defined($name) || ref $name ) {
802 2 50       7 $name = defined $name ? $name : 'undef';
803 2         24 die
804             qq{Str: invalid value $name for variable \$name in method build_accessor_default};
805             }
806 2 50 33     11 if ( !defined($content) || ref $content ) {
807 2 50       6 $content = defined $content ? $content : 'undef';
808 2         22 die
809             qq{Str: invalid value $content for variable \$content in method build_accessor_default};
810             }
811              
812 0           return q|sub {| . $content . q|}|;
813              
814             }
815              
816             1;
817              
818             __END__
819              
820             =head1 NAME
821              
822             Hades::Realm::OO - Hades realm for object orientation
823              
824             =head1 VERSION
825              
826             Version 0.08
827              
828             =cut
829              
830             =head1 SYNOPSIS
831              
832             Quick summary of what the module does:
833              
834             Hades::Realm::Kosmos base Hades::Realm::OO {
835             ...
836             }
837              
838             =head1 SUBROUTINES/METHODS
839              
840             =head2 new
841              
842             Instantiate a new Hades::Realm::OO object.
843              
844             Hades::Realm::OO->new
845              
846             =head2 clear_is_role
847              
848             clear is_role accessor
849              
850             $obj->clear_is_role
851              
852             =head2 module_generate
853              
854             call module_generate method. Expects param $mg to be a Object.
855              
856             $obj->module_generate($mg)
857              
858             =head2 build_class_inheritance
859              
860             call build_class_inheritance method.
861              
862             =head2 build_new
863              
864             call build_new method. Expects param $mg to be a Object, param $meta to be a HashRef, param $types to be a HashRef.
865              
866             $obj->build_new($mg, $meta, $types)
867              
868             =head2 build_clearer
869              
870             call build_clearer method.
871              
872             =head2 build_predicate
873              
874             call build_predicate method.
875              
876             =head2 build_accessor_no_arguments
877              
878             call build_accessor_no_arguments method. Expects param $mg to be a Object, param $token to be a ArrayRef, param $meta to be a HashRef.
879              
880             $obj->build_accessor_no_arguments($mg, $token, $meta)
881              
882             =head2 build_accessor
883              
884             call build_accessor method. Expects param $mg to be a Object, param $name to be a Str, param $meta to be a HashRef.
885              
886             $obj->build_accessor($mg, $name, $meta)
887              
888             =head2 build_sub
889              
890             call build_sub method. Expects param $mg to be a Object, param $name to be a Str, param $meta to be a HashRef.
891              
892             $obj->build_sub($mg, $name, $meta)
893              
894             =head2 build_modify
895              
896             call build_modify method. Expects param $mg to be a Object, param $name to be a Str, param $meta to be a HashRef.
897              
898             $obj->build_modify($mg, $name, $meta)
899              
900             =head2 after_class
901              
902             call after_class method. Expects param $mg to be a Object, param $meta to be a HashRef.
903              
904             $obj->after_class($mg, $meta)
905              
906             =head2 unique_types
907              
908             call unique_types method. Expects param $type to be a Str, param $unique to be a HashRef.
909              
910             $obj->unique_types($type, $unique)
911              
912             =head2 build_as_class
913              
914             call build_as_class method. Expects param $mg to be a Object, param $meta to be a HashRef.
915              
916             $obj->build_as_class($mg, $meta)
917              
918             =head2 build_as_role
919              
920             call build_as_role method. Expects param $mg to be a Object, param $meta to be a HashRef.
921              
922             $obj->build_as_role($mg, $meta)
923              
924             =head2 build_has_keywords
925              
926             call build_has_keywords method. Expects param $keywords to be a ArrayRef.
927              
928             $obj->build_has_keywords($keywords)
929              
930             =head2 build_has
931              
932             call build_has method. Expects param $meta to be a HashRef.
933              
934             $obj->build_has($meta)
935              
936             =head2 build_function_keywords
937              
938             call build_function_keywords method. Expects param $keywords to be a ArrayRef.
939              
940             $obj->build_function_keywords($keywords)
941              
942             =head2 build_function
943              
944             call build_function method. Expects param $meta to be a HashRef.
945              
946             $obj->build_function($meta)
947              
948             =head2 build_extends_keywords
949              
950             call build_extends_keywords method. Expects param $keywords to be a ArrayRef.
951              
952             $obj->build_extends_keywords($keywords)
953              
954             =head2 build_extends
955              
956             call build_extends method. Expects param $meta to be a HashRef.
957              
958             $obj->build_extends($meta)
959              
960             =head2 build_with_keywords
961              
962             call build_with_keywords method. Expects param $keywords to be a ArrayRef.
963              
964             $obj->build_with_keywords($keywords)
965              
966             =head2 build_with
967              
968             call build_with method. Expects param $meta to be a HashRef.
969              
970             $obj->build_with($meta)
971              
972             =head2 build_requires_keywords
973              
974             call build_requires_keywords method. Expects param $keywords to be a ArrayRef.
975              
976             $obj->build_requires_keywords($keywords)
977              
978             =head2 build_requires
979              
980             call build_requires method. Expects param $meta to be a HashRef.
981              
982             $obj->build_requires($meta)
983              
984             =head2 build_before_keywords
985              
986             call build_before_keywords method. Expects param $keywords to be a ArrayRef.
987              
988             $obj->build_before_keywords($keywords)
989              
990             =head2 build_before
991              
992             call build_before method. Expects param $meta to be a HashRef.
993              
994             $obj->build_before($meta)
995              
996             =head2 build_around_keywords
997              
998             call build_around_keywords method. Expects param $keywords to be a ArrayRef.
999              
1000             $obj->build_around_keywords($keywords)
1001              
1002             =head2 build_around
1003              
1004             call build_around method. Expects param $meta to be a HashRef.
1005              
1006             $obj->build_around($meta)
1007              
1008             =head2 build_after_keywords
1009              
1010             call build_after_keywords method. Expects param $keywords to be a ArrayRef.
1011              
1012             $obj->build_after_keywords($keywords)
1013              
1014             =head2 build_after
1015              
1016             call build_after method. Expects param $meta to be a HashRef.
1017              
1018             $obj->build_after($meta)
1019              
1020             =head2 build_accessor_builder
1021              
1022             call build_accessor_builder method. Expects param $name to be a Str, param $content to be a Str.
1023              
1024             $obj->build_accessor_builder($name, $content)
1025              
1026             =head2 build_accessor_coerce
1027              
1028             call build_accessor_coerce method. Expects param $name to be a Str, param $content to be a Str.
1029              
1030             $obj->build_accessor_coerce($name, $content)
1031              
1032             =head2 build_accessor_trigger
1033              
1034             call build_accessor_trigger method. Expects param $name to be a Str, param $content to be a Str.
1035              
1036             $obj->build_accessor_trigger($name, $content)
1037              
1038             =head2 build_accessor_default
1039              
1040             call build_accessor_default method. Expects param $name to be a Str, param $content to be a Str.
1041              
1042             $obj->build_accessor_default($name, $content)
1043              
1044             =head1 ACCESSORS
1045              
1046             =head2 current_class
1047              
1048             get or set current_class.
1049              
1050             $obj->current_class;
1051              
1052             $obj->current_class($value);
1053              
1054             =head2 meta
1055              
1056             get or set meta.
1057              
1058             $obj->meta;
1059              
1060             $obj->meta($value);
1061              
1062             =head2 is_role
1063              
1064             get or set is_role.
1065              
1066             $obj->is_role;
1067              
1068             $obj->is_role($value);
1069              
1070             =head1 AUTHOR
1071              
1072             LNATION, C<< <email at lnation.org> >>
1073              
1074             =head1 BUGS
1075              
1076             Please report any bugs or feature requests to C<bug-hades::realm::oo at rt.cpan.org>, or through
1077             the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Hades-Realm-OO>. I will be notified, and then you'll
1078             automatically be notified of progress on your bug as I make changes.
1079              
1080             =head1 SUPPORT
1081              
1082             You can find documentation for this module with the perldoc command.
1083              
1084             perldoc Hades::Realm::OO
1085              
1086             You can also look for information at:
1087              
1088             =over 4
1089              
1090             =item * RT: CPAN's request tracker (report bugs here)
1091              
1092             L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Hades-Realm-OO>
1093              
1094             =item * AnnoCPAN: Annotated CPAN documentation
1095              
1096             L<http://annocpan.org/dist/Hades-Realm-OO>
1097              
1098             =item * CPAN Ratings
1099              
1100             L<https://cpanratings.perl.org/d/Hades-Realm-OO>
1101              
1102             =item * Search CPAN
1103              
1104             L<https://metacpan.org/release/Hades-Realm-OO>
1105              
1106             =back
1107              
1108             =head1 ACKNOWLEDGEMENTS
1109              
1110             =head1 LICENSE AND COPYRIGHT
1111              
1112             This software is Copyright (c) 2020 by LNATION.
1113              
1114             This is free software, licensed under:
1115              
1116             The Artistic License 2.0 (GPL Compatible)
1117              
1118             =cut
1119              
1120