File Coverage

blib/lib/Class/MakeMethods/Template.pm
Criterion Covered Total %
statement 241 293 82.2
branch 115 170 67.6
condition 43 74 58.1
subroutine 24 28 85.7
pod 0 2 0.0
total 423 567 74.6


line stmt bran cond sub pod time code
1             package Class::MakeMethods::Template;
2              
3 93     93   1740 use strict;
  93         173  
  93         7215  
4 93     93   530 use Carp;
  93         206  
  93         9147  
5              
6 93     93   69616 use Class::MakeMethods '-isasubclass';
  93         238  
  93         787  
7              
8 93     93   515 use vars qw( $VERSION );
  93         180  
  93         9051  
9             $VERSION = 1.008;
10              
11 2083     2083   5882 sub _diagnostic { &Class::MakeMethods::_diagnostic }
12              
13             ########################################################################
14             ### TEMPLATE LOOKUP AND CACHING: named_method(), _definition()
15             ########################################################################
16              
17 93     93   648 use vars qw( %TemplateCache );
  93         188  
  93         529082  
18              
19             # @results = $class->named_method( $name, @arguments );
20             sub named_method {
21 5279     5279 0 7510 my $class = shift;
22 5279         18676 my $name = shift;
23            
24             # Support direct access to cached Template information
25 5279 100       22333 if (exists $TemplateCache{"$class\::$name"}) {
26 4531         39430 return $TemplateCache{"$class\::$name"};
27             }
28            
29 748         4183 my @results = $class->$name( @_ );
30            
31 748 100 100     8241 if ( scalar @results == 1 and ref $results[0] eq 'HASH' ) {
32             # If this is a hash-definition format, cache the results for speed.
33 739         1597 my $def = $results[0];
34 739         2762 $TemplateCache{"$class\::$name"} = $def;
35 739         3760 _expand_definition($class, $name, $def);
36 739         12622 return $def;
37             }
38            
39 9 50       49 return wantarray ? @results : $results[0];
40             }
41              
42             # $mm_def = _definition( $class, $target );
43             sub _definition {
44 5059     5059   7873 my ($class, $target) = @_;
45            
46 5059         11698 while ( ! ref $target ) {
47 5059         19619 $target =~ s/\s.*//;
48            
49             # If method name contains a colon or double colon, call the method on the
50             # indicated class.
51 5059 50       38258 my $call_class = ( ( $target =~ s/^(.*)\:{1,2}// )
52             ? Class::MakeMethods::_find_subclass($class, $1) : $class );
53 5059         18555 $target = $call_class->named_method( $target );
54             }
55 5059 50 66     24188 _diagnostic('mmdef_not_interpretable', $target)
56             unless ( ref($target) eq 'HASH' or ref($target) eq __PACKAGE__ );
57            
58 5059         11754 return $target;
59             }
60              
61             ########################################################################
62             ### TEMPLATE INTERNALS: _expand_definition()
63             ########################################################################
64              
65             sub _expand_definition {
66 739     739   1410 my ($class, $name, $mm_def) = @_;
67            
68 739 50       1925 return $mm_def if $mm_def->{'-parsed'};
69            
70 739         1431 $mm_def->{'template_class'} = $class;
71 739         1327 $mm_def->{'template_name'} = $name;
72            
73             # Allow definitions to import values from each other.
74 739         879 my $importer;
75 739         2296 foreach $importer ( qw( interface params behavior code_expr modifier ) ) {
76 3695   100     22611 my $rules = $mm_def->{$importer}->{'-import'} || $mm_def->{'-import'};
77 3695 50       14974 my @rules = ( ref $rules eq 'HASH' ? %$rules : ref $rules eq 'ARRAY' ? @$rules : () );
    100          
78 3695 100       36914 unshift @rules, '::' . $class . ':generic' => '*' if $class->can('generic');
79 3695         13101 while (
80             my ($source, $names) = splice @rules, 0, 2
81             ) {
82 5059         12392 my $mmi = _definition($class, $source);
83 5059 100       10907 foreach ( ( $names eq '*' ) ? keys %{ $mmi->{$importer} }
  4772 100       24799  
  11         33  
84             : ( ref $names ) ? @{ $names } : ( $names ) ) {
85 21961         43945 my $current = $mm_def->{$importer}{$_};
86 21961         35901 my $import = $mmi->{$importer}{$_};
87 21961 100       49222 if ( ! $current ) {
    100          
88 15231         56612 $mm_def->{$importer}{$_} = $import;
89             } elsif ( ref($current) eq 'ARRAY' ) {
90 168 50       1280 my @imports = ref($import) ? @$import : $import;
91 168         411 foreach my $imp ( @imports ) {
92 1554 100       2197 push @$current, $imp unless ( grep { $_ eq $imp } @$current );
  15414         28459  
93             }
94             }
95             }
96             }
97 3695         11694 delete $mm_def->{$importer}->{'-import'};
98             }
99 739         1502 delete $mm_def->{'-import'};
100            
101 739 50       2074 _describe_definition( $mm_def ) if $Class::MakeMethods::CONTEXT{Debug};
102              
103            
104 739         2514 $mm_def->{'-parsed'} = "$_[1]";
105            
106 739         2657 bless $mm_def, __PACKAGE__;
107             }
108              
109             sub _describe_definition {
110 0     0   0 my $mm_def = shift;
111            
112 0         0 my $def_type = "$mm_def->{template_class}:$mm_def->{template_name}";
113 0         0 warn "----\nMethods info for $def_type:\n";
114 0 0       0 if ( $mm_def->{interface} ) {
115 0         0 warn join '', "Templates: \n", map {
116 0         0 " $_: " . _describe_value($mm_def->{interface}{$_}) . "\n"
117 0         0 } keys %{$mm_def->{interface}};
118             }
119 0 0       0 if ( $mm_def->{modifier} ) {
120 0         0 warn join '', "Modifiers: \n", map {
121 0         0 " $_: " . _describe_value($mm_def->{modifier}{$_}) . "\n"
122 0         0 } keys %{$mm_def->{modifier}};
123             }
124             }
125              
126             sub _describe_value {
127 0     0   0 my $value = $_[0];
128 0 0       0 ref($value) eq 'ARRAY' ? join(', ', @$value) :
    0          
129             ref($value) eq 'HASH' ? join(', ', %$value) :
130             "$value";
131             }
132              
133             ########################################################################
134             ### METHOD GENERATION: make_methods()
135             ########################################################################
136              
137             sub make_methods {
138 211     211 0 432 my $mm_def = shift;
139            
140 211 100       805 return unless ( scalar @_ );
141            
142             # Select default interface and initial method parameters
143 210   50     384 my $defaults = { %{ ( $mm_def->{'params'} ||= {} ) } };
  210         1506  
144 210   50     2475 $defaults->{'interface'} ||= $mm_def->{'interface'}{'-default'} || 'default';
      33        
145 210         1373 $defaults->{'target_class'} = $mm_def->_context('TargetClass');
146 210         614 $defaults->{'template_class'} = $mm_def->{'template_class'};
147 210         642 $defaults->{'template_name'} = $mm_def->{'template_name'};
148            
149 210         407 my %interface_cache;
150            
151             # Our return value is the accumulated list of method-name => method-sub pairs
152             my @methods;
153              
154 210         771 while (scalar @_) {
155              
156             ### PARSING ### Requires: $mm_def, $defaults, @_
157            
158 458         1628 my $m_name = shift @_;
159 458 50 33     4397 _diagnostic('make_empty') unless ( defined $m_name and length $m_name );
160            
161             # Normalize: If we've got an array of names, replace it with those names
162 458 100       1345 if ( ref $m_name eq 'ARRAY' ) {
163 2         4 my @items = @{ $m_name };
  2         11  
164             # If array is followed by a params hash, each one gets the same params
165 2 50 33     38 if ( scalar @_ and ref $_[0] eq 'HASH' and ! exists $_[0]->{'name'} ) {
      33        
166 0         0 my $params = shift;
167 0         0 @items = map { $_, $params } @items
  0         0  
168             }
169 2         9 unshift @_, @items;
170 2         10 next;
171             }
172            
173             # Parse interfaces, modifiers and parameters
174 456 100       1846 if ( $m_name =~ s/^-// ) {
175 131 100       628 if ( $m_name !~ s/^-// ) {
176             # -param => value
177 60         165 $defaults->{$m_name} = shift @_;
178             } else {
179 71 50       437 if ( $m_name eq '' ) {
    100          
    100          
    50          
180             # '--' => { param => value ... }
181 0         0 %$defaults = ( %$defaults, %{ shift @_ } );
  0         0  
182            
183             } elsif ( exists $mm_def->{'interface'}{$m_name} ) {
184             # --interface
185 51         118 $defaults->{'interface'} = $m_name;
186            
187             } elsif ( exists $mm_def->{'modifier'}{$m_name} ) {
188             # --modifier
189 9 100       36 $defaults->{'modifier'} .=
190             ( $defaults->{'modifier'} ? ' ' : '' ) . "-$m_name";
191            
192             } elsif ( exists $mm_def->{'behavior'}{$m_name} ) {
193             # --behavior as shortcut for single-method interface
194 11         24 $defaults->{'interface'} = $m_name;
195            
196             } else {
197 0         0 _diagnostic('make_bad_modifier', $mm_def->{'name'}, "--$m_name");
198             }
199             }
200 131         450 next;
201             }
202            
203             # Make a new meta-method hash
204 325         495 my $m_info;
205            
206             # Parse string, string-then-hash, and hash-only meta-method parameters
207 325 100       1065 if ( ! ref $m_name ) {
    50          
208 297 100 100     1899 if ( scalar @_ and ref $_[0] eq 'HASH' and ! exists $_[0]->{'name'} ) {
      100        
209 8         15 %$m_info = ( 'name' => $m_name, %{ shift @_ } );
  8         60  
210             } else {
211 289         1296 $m_info = { 'name' => $m_name };
212             }
213            
214             } elsif ( ref $m_name eq 'HASH' ) {
215 28 50 33     292 unless ( exists $m_name->{'name'} and length $m_name->{'name'} ) {
216 0         0 _diagnostic('make_noname');
217             }
218 28         170 $m_info = { %$m_name };
219            
220             } else {
221 0         0 _diagnostic('make_unsupported', $m_name);
222             }
223 325 50       2586 _diagnostic('debug_declaration', join(', ', map { defined $_ ? $_ : '(undef)' } %$m_info) );
  742         3236  
224              
225             ### INITIALIZATION ### Requires: $mm_def, $defaults, $m_info
226            
227 325   66     4706 my $interface = (
      66        
      66        
228             $interface_cache{ $m_info->{'interface'} || $defaults->{'interface'} }
229             ||= _interpret_interface( $mm_def, $m_info->{'interface'} || $defaults->{'interface'} )
230             );
231 12         166 %$m_info = (
232             %$defaults,
233 325 100       4823 ( $interface->{-params} ? %{$interface->{-params}} : () ),
234             %$m_info
235             );
236              
237            
238             # warn "Actual: " . Dumper( $m_info );
239              
240              
241             # Expand * and *{...} strings.
242 325         2332 foreach (grep defined $m_info->{$_}, keys %$m_info) {
243 2137   100     6204 $m_info->{$_} =~ s/\*(?:\{([^\}]+)?\})?/ $m_info->{ $1 || 'name' } /ge
  285         2570  
244             }
245 325 100 66     1581 if ( $m_info->{'modifier'} and $mm_def->{modifier}{-folding} ) {
246 7         25 $m_info->{'modifier'} = _fold_modifiers( $m_info->{'modifier'},
247             $mm_def->{modifier}{-folding} )
248             }
249            
250             ### METHOD GENERATION ### Requires: $mm_def, $interface, $m_info
251            
252             # If the MM def provides an initialization "-init" call, run it.
253 325 100       1759 if ( local $_ = $mm_def->{'behavior'}->{'-init'} ) {
254 63 100       387 push @methods, map $_->( $m_info ), (ref($_) eq 'ARRAY') ? @$_ : $_;
255             }
256             # Build Methods
257 325         4193 for ( grep { /^[^-]/ } keys %$interface ) {
  1668         8148  
258 1331         2531 my $function_name = $_;
259 1331         5896 $function_name =~ s/\*/$m_info->{'name'}/g;
260            
261 1331         3138 my $behavior = $interface->{$_};
262            
263             # Fold in additional modifiers
264 1331 100       5183 if ( $m_info->{'modifier'} ) {
265 6 50 33     25 if ( $behavior =~ /^\-/ and $mm_def->{modifier}{-folding} ) {
266 0         0 $behavior = $m_info->{'modifier'} =
267             _fold_modifiers( "$m_info->{'modifier'} $behavior",
268             $mm_def->{modifier}{-folding} )
269             } else {
270 6         17 $behavior = "$m_info->{'modifier'} $behavior";
271             }
272             }
273              
274 1331 100       5663 my $builder =
    100          
275             ( $mm_def->{'-behavior_cache'}{$behavior} ) ?
276             $mm_def->{'-behavior_cache'}{$behavior} :
277             ( ref($mm_def->{'behavior'}{$behavior}) eq 'CODE' ) ?
278             $mm_def->{'behavior'}{$behavior} :
279             _behavior_builder( $mm_def, $behavior, $m_info );
280            
281 1331         40735 my $method = &$builder( $m_info );
282            
283 1331         3387 _diagnostic('debug_make_behave', $behavior, $function_name, $method);
284 1331 50       14373 push @methods, ($function_name => $method) if ($method);
285             }
286            
287             # If the MM def provides a "-subs" call, for forwarding and other
288             # miscelaneous "subsidiary" or "contained" methods, run it.
289 325 100       1623 if ( my $subs = $mm_def->{'behavior'}->{'-subs'} ) {
290 29 50       108 my @subs = (ref($subs) eq 'ARRAY') ? @$subs : $subs;
291 29         59 foreach my $sub ( @subs ) {
292 29         1510 my @results = $sub->($m_info);
293 29 50 33     193 if ( scalar @results == 1 and ref($results[0]) eq 'HASH' ) {
294             # If it returns a hash of helper method types, check the method info
295             # for any matching names and call the corresponding method generator.
296 29         48 my $types = shift @results;
297 29         88 foreach my $type ( keys %$types ) {
298 55 100       268 my $names = $m_info->{$type} or next;
299 11 100       59 my @names = ref($names) eq 'ARRAY' ? @$names : split(' ', $names);
300 11         26 my $generator = $types->{$type};
301 11         27 push @results, map { $_ => &$generator($m_info, $_) } @names;
  11         41  
302             }
303             }
304 29         117 push @methods, @results;
305             }
306             }
307            
308             # If the MM def provides a "-register" call, for registering meta-method
309             # information for run-time access, run it.
310 325 100       2099 if ( local $_ = $mm_def->{'behavior'}->{'-register'} ) {
311 13 50       92 push @methods, map $_->( $m_info ), (ref($_) eq 'ARRAY') ? @$_ : $_;
312             }
313             }
314            
315 210         3767 return @methods;
316             }
317              
318             # I'd like for the make_methods() sub to be simpler, and to take advantage
319             # of the standard _get_declarations parsing provided by the superclass.
320             # Sadly the below doesn't work, due to a few order-of-operations peculiarities
321             # of parsing interfaces and modifiers, and their associated default paramters.
322             # Perhaps it might work if the processing of --options could be overridden with
323             # a callback sub, so that interfaces and their params can be parsed in order.
324             sub _x_get_declarations {
325 0     0   0 my $mm_def = shift;
326              
327 0         0 my @declarations = $mm_def::SUPER->_get_declarations( @_ );
328              
329             # use Data::Dumper;
330             # warn "In: " . Dumper( \@_ );
331             # warn "Auto: " . Dumper( \@declarations );
332              
333 0         0 my %interface_cache;
334              
335 0         0 while (scalar @declarations) {
336            
337 0         0 my $m_info = shift @declarations;
338              
339             # Parse interfaces and modifiers
340 0   0     0 my @specials = grep $_, split '--', ( delete $m_info->{'--'} || '' );
341 0         0 foreach my $special ( @specials ) {
342 0 0       0 if ( exists $mm_def->{'interface'}{$special} ) {
    0          
    0          
343             # --interface
344 0         0 $m_info->{'interface'} = $special;
345            
346             } elsif ( exists $mm_def->{'modifier'}{$special} ) {
347             # --modifier
348 0 0       0 $m_info->{'modifier'} .=
349             ( $m_info->{'modifier'} ? ' ' : '' ) . "-$special";
350            
351             } elsif ( exists $mm_def->{'behavior'}{$special} ) {
352             # --behavior as shortcut for single-method interface
353 0         0 $m_info->{'interface'} = $special;
354            
355             } else {
356 0         0 _diagnostic('make_bad_modifier', $mm_def->{'name'}, "--$special");
357             }
358             }
359              
360 0   0     0 my $interface = (
361             $interface_cache{ $m_info->{'interface'} }
362             ||= _interpret_interface( $mm_def, $m_info->{'interface'} )
363             );
364 0 0       0 $m_info = { %$m_info, %{$interface->{-params}} } if $interface->{-params};
  0         0  
365              
366 0 0       0 _diagnostic('debug_declaration', join(', ', map { defined $_ ? $_ : '(undef)' } %$m_info) );
  0         0  
367            
368             # warn "Updated: " . Dumper( $m_info );
369             }
370             }
371              
372             ########################################################################
373             ### TEMPLATES: _interpret_interface()
374             ########################################################################
375              
376             sub _interpret_interface {
377 216     216   671 my ($mm_def, $interface) = @_;
378            
379 216 100 33     4707 if ( ref $interface eq 'HASH' ) {
    50          
    50          
    0          
380 49 100       232 return $interface if exists $interface->{'-parsed'};
381             }
382             elsif ( ! defined $interface or ! length $interface ) {
383 0         0 _diagnostic('tmpl_empty');
384              
385             }
386             elsif ( ! ref $interface ) {
387 167 100       2218 if ( exists $mm_def->{'interface'}{ $interface } ) {
    50          
388 163 100       765 if ( ! ref $mm_def->{'interface'}{ $interface } ) {
389 66         370 $mm_def->{'interface'}{ $interface } =
390             { '*' => $mm_def->{'interface'}{ $interface } };
391             }
392             } elsif ( exists $mm_def->{'behavior'}{ $interface } ) {
393 4         18 $mm_def->{'interface'}{ $interface } = { '*' => $interface };
394             } else {
395 0         0 _diagnostic('tmpl_unkown', $interface);
396             }
397 167         446 $interface = $mm_def->{'interface'}{ $interface };
398            
399 167 100       912 return $interface if exists $interface->{'-parsed'};
400             }
401             elsif ( ref $interface ne 'HASH' ) {
402 0         0 _diagnostic('tmpl_unsupported', $interface);
403             }
404            
405 155         869 $interface->{'-parsed'} = "$_[1]";
406            
407             # Allow interface inheritance via -base specification
408 155 100       717 if ( $interface->{'-base'} ) {
409 1         6 for ( split ' ', $interface->{'-base'} ) {
410 1         7 my $base = _interpret_interface( $mm_def, $_ );
411 1         11 %$interface = ( %$base, %$interface );
412             }
413 1         3 delete $interface->{'-base'};
414             }
415            
416 155         778 for (keys %$interface) {
417             # Remove empty/undefined items.
418 707 50 33     4326 unless ( defined $interface->{$_} and length $interface->{$_} ) {
419 0         0 delete $interface->{$_};
420 0         0 next;
421             }
422             }
423             # _diagnostic('debug_interface', $_[1], join(', ', %$interface ));
424            
425 155         1273 return $interface;
426             }
427              
428             ########################################################################
429             ### BEHAVIORS AND MODIFIERS: _fold_modifiers(), _behavior_builder()
430             ########################################################################
431              
432             sub _fold_modifiers {
433 7     7   13 my $spec = shift;
434 7         8 my $rules = shift;
435 7         35 my %rules = @$rules;
436            
437             # Longest first, to prevent over-eager matching.
438 51         99 my $rule = join '|', map "\Q$_\E",
439 7         29 sort { length($b) <=> length($a) } keys %rules;
440             # Match repeatedly from the front.
441 7         309 1 while ( $spec =~ s/($rule)/$rules{$1}/ );
442 7         37 $spec =~ s/(^|\s)\s/$1/g;
443 7         32 return $spec;
444             }
445              
446             sub _behavior_builder {
447 427     427   744 my ( $mm_def, $behavior, $m_info ) = @_;
448            
449             # We're going to have to do some extra work here, so we'll cache the result
450 427         666 my $builder;
451            
452             # Separate the modifiers
453 427         622 my $core_behavior = $behavior;
454 427         753 my @modifiers;
455 427         1488 while ( $core_behavior =~ s/\-(\w+)\s// ) { push @modifiers, $1 }
  4         19  
456            
457             # Find either the built-in or universal behavior template
458 427 50       1338 if ( $mm_def->{'behavior'}{$core_behavior} ) {
459 427         879 $builder = $mm_def->{'behavior'}{$core_behavior};
460             } else {
461 0         0 my $universal = _definition('Class::MakeMethods::Template::Universal','generic');
462 0         0 $builder = $universal->{'behavior'}{$core_behavior}
463             }
464            
465             # Otherwise we're hosed.
466 427 50       1085 $builder or _diagnostic('make_bad_behavior', $m_info->{'name'}, $behavior);
467            
468 427 50       1088 if ( ! ref $builder ) {
    0          
469             # If we've got a text template, pass it off for interpretation.
470 427 50       1830 my $code = ( ! $Class::MakeMethods::Utility::DiskCache::DiskCacheDir ) ?
471             _interpret_text_builder($mm_def, $core_behavior, $builder, @modifiers)
472             : _disk_cache_builder($mm_def, $core_behavior, $builder, @modifiers);
473            
474             # _diagnostic('debug_eval_builder', $name, $code);
475 427 50       2903 local $^W unless $Class::MakeMethods::CONTEXT{Debug};
476 427 100 100 460   76069 $builder = eval $code;
  460 100 100 1   45191  
  460 100   1   2272  
  283 100   1   4875  
  329 100   1   2436  
  267     1   7141  
  261     1   2809  
  220     1   7554  
  200     1   2137  
  179     1   3838  
  156         1734  
  175         3186  
  134         1687  
  185         7372  
  152         1301  
  98         2327  
  145         2233  
  156         719  
  141         771  
  150         2998  
  154         2307  
  111         837  
  171         1757  
  148         2133  
  141         764  
  68         1305  
  71         455  
  58         804  
  43         246  
  44         344  
  45         963  
  74         1796  
  74         1585  
  71         249  
  56         681  
  61         827  
  50         1341  
  33         167  
  45         1048  
  58         515  
  58         405  
  39         215  
  50         320  
  55         591  
  32         318  
  25         121  
  24         307  
477 427 50       1471 if ( $@ ) { _diagnostic('behavior_eval', $@, $code) }
  0         0  
478 427 50       1935 unless (ref $builder eq 'CODE') { _diagnostic('behavior_eval', $@, $code) }
  0         0  
479            
480             } elsif ( scalar @modifiers ) {
481             # Can't modify code subs
482 0         0 _diagnostic('make_behavior_mod', join(', ', @modifiers), $core_behavior);
483             }
484            
485 427         1492 $mm_def->{'-behavior_cache'}{$behavior} = $builder;
486              
487 427         1169 return $builder;
488             }
489              
490             ########################################################################
491             ### CODE EXPRESSIONS: _interpret_text_builder(), _disk_cache_builder()
492             ########################################################################
493              
494             sub _interpret_text_builder {
495 427     427   97310 require Class::MakeMethods::Utility::TextBuilder;
496            
497 427         1360 my ( $mm_def, $name, $code, @modifiers ) = @_;
498            
499 427         1059 foreach ( @modifiers ) {
500 4 50       21 exists $mm_def->{'modifier'}{$_}
501             or _diagnostic('behavior_mod_unknown', $name, $_);
502             }
503            
504 1708   66     2906 my @exprs = grep { $_ } map {
  854         6639  
505 427 100       1323 $mm_def->{'modifier'}{ $_ },
506             $mm_def->{'modifier'}{ "$_ $name" } || $mm_def->{'modifier'}{ "$_ *" }
507             } ( '-all', ( scalar(@modifiers) ? @modifiers : '-default' ) );
508            
509             # Generic method template
510 427         864 push @exprs, "return sub _SUB_ATTRIBS_ { \n my \$self = shift;\n * }";
511            
512             # Closure-generator
513 427         648 push @exprs, "sub { my \$m_info = \$_[0]; * }";
514            
515 427         769 my $exprs = $mm_def->{code_expr};
516 8765         19465 unshift @exprs, {
517 427         6541 ( map { $_=>$exprs->{$_} } grep /^[^-]/, keys %$exprs ),
518             '_BEHAVIOR_{}' => $mm_def->{'behavior'},
519             '_SUB_ATTRIBS_' => '',
520             };
521            
522 427         2914 my $result = Class::MakeMethods::Utility::TextBuilder::text_builder($code,
523             @exprs);
524            
525 427         1238 my $modifier_string = join(' ', map "-$_", @modifiers);
526 427 100       2431 my $full_name = "$name ($mm_def->{template_class} $mm_def->{template_name}" .
527             ( $modifier_string ? " $modifier_string" : '' ) . ")";
528            
529 427         1202 _diagnostic('debug_template_builder', $full_name, $code, $result);
530            
531 427         8642 return $result;
532             }
533              
534             sub _disk_cache_builder {
535 0     0   0 require Class::MakeMethods::Utility::DiskCache;
536 0         0 my ( $mm_def, $core_behavior, $builder, @modifiers ) = @_;
537            
538 0         0 Class::MakeMethods::Utility::DiskCache::disk_cache(
539             "$mm_def->{template_class}::$mm_def->{template_name}",
540             join('.', $core_behavior, @modifiers),
541             \&_interpret_text_builder, ($mm_def, $core_behavior, $builder, @modifiers)
542             );
543             }
544              
545             1;
546              
547             __END__