File Coverage

blib/lib/Class/Injection.pm
Criterion Covered Total %
statement 18 213 8.4
branch 1 66 1.5
condition 0 20 0.0
subroutine 6 12 50.0
pod 5 5 100.0
total 30 316 9.4


line stmt bran cond sub pod time code
1             package Class::Injection; ## Injects methods to other classes
2              
3 1     1   658 use 5.006;
  1         3  
4 1     1   421 use Class::Inspector;
  1         2735  
  1         32  
5 1     1   16 use strict;
  1         2  
  1         20  
6 1     1   763 use Data::Dumper;
  1         4597  
  1         85  
7              
8             our $VERSION = '1.10';
9              
10             our $DEBUG;
11             our $info_store={};
12             our $break_flag;
13              
14 1     1   6 no warnings;
  1         1  
  1         1367  
15              
16              
17              
18              
19              
20             ## The import function is called by Perl when the class is included by 'use'.
21             ## It takes the parameters after the 'use Class::Injection' call.
22             ## This function stores your intention of injection in the static collector
23             ## variable. Later you can call install() function to overwrite or append the methods.
24             sub import{
25 1     1   8 my $pkg=shift;
26 1         1 my $target=shift; # the first parameter, which is the target
27              
28 1 50       3 if (!$target){return};
  1         13  
29              
30 0           my $secondvalue = shift;
31              
32 0           my $copymethod;
33             my $priority;
34 0           my $returntype;
35 0           my $returnmethod;
36 0           my $replacetarget;
37            
38              
39             ## if the second value is a hashref, asign the elements
40 0 0         if ( ref($secondvalue) ){
41              
42 0   0       $copymethod = $secondvalue->{'how'} || $secondvalue->{'copymethod'};
43 0           $priority = $secondvalue->{'priority'};
44 0   0       $returntype = $secondvalue->{'returns'} || $secondvalue->{'returntype'} || '';
45 0   0       $returnmethod = $secondvalue->{'returnmethod'} || 'last';
46 0 0 0       $DEBUG = $DEBUG || $secondvalue->{'debug'} =~ m/^(true|yes|1)$/i ? 1 : 0;
47              
48 0 0         $replacetarget = $secondvalue->{'replace'} =~ m/^(true|yes|1)$/i ? 1 : 0;
49              
50             }else{ ## if the second value is NOT a ref, take copymethod and prio
51 0   0       $copymethod = $secondvalue || 'replace';
52 0           $priority = shift; ## default prio is 1
53             }
54              
55 0 0         if ( $copymethod eq 'replace' ){
56 0           $replacetarget = 1;
57             }
58              
59            
60 0           my @caller=caller;
61 0           my $class = shift @caller; # calling class (which has 'use Class::Injection')
62              
63             ## used for insert and append
64 0           $Class::Injection::counter_neg--;
65 0           $Class::Injection::counter_pos++;
66            
67 0 0         if ($priority < $Class::Injection::counter_neg){
68 0           $Class::Injection::counter_neg = $priority - 1;
69             }
70              
71 0 0         if ($priority < $Class::Injection::counter_pos){
72 0           $Class::Injection::counter_pos = $priority + 1;
73             }
74              
75            
76              
77             ## setting default priorities
78 0 0         if ( $priority eq "" ){
79 0 0         if ( $copymethod eq 'insert'){
80 0           $priority = $Class::Injection::counter_neg;
81             }else{ ## add or append
82 0           $priority = $Class::Injection::counter_pos;
83             }
84             }
85            
86              
87            
88 0 0         if (!$target) {
89 0           die __PACKAGE__." expects a parameter as target class in the use line."
90             }
91              
92            
93             ## collection the classnames using the injector
94 0   0       $__PACKAGE__::collector ||= {};
95 0           $__PACKAGE__::collector->{$class} = { target => $target,
96             priority => $priority,
97             copymethod => $copymethod,
98             returntype => $returntype,
99             returnmethod => $returnmethod,
100             replacetarget => $replacetarget,
101             };
102             }
103              
104              
105              
106              
107              
108             ## Installs the methods to existing classes. Do not try to call this method in a BEGIN block,
109             ## the needed environment does not exist so far.
110             sub install{
111              
112 0     0 1   my $col = $__PACKAGE__::collector;
113              
114 0 0         if ($DEBUG){
115 0           print "collected methods:\n";
116 0           print Dumper($col);
117             }
118              
119            
120              
121 0           my $sources_by_target={};
122              
123 0           foreach my $source (keys %{ $col }) { ## loop per source class
  0            
124            
125 0           my $target = $col->{$source}->{'target'};
126 0           my $copymethod = $col->{$source}->{'copymethod'};
127 0           my $priority = $col->{$source}->{'priority'};
128              
129             ## check if source exists on the memory (is loaded via 'use')
130 0 0         if (!Class::Inspector->loaded( $source )) {
131 0 0         if (!Class::Inspector->installed($source)) {
132 0           die "Class \'$source\' not installed on this machine or path not in \@INC.";
133             }
134 0           die "Class \'$source\' not loaded.";
135             }
136              
137             ## read the methods of the source class
138 0           my $functions = Class::Inspector->functions( $source );
139              
140              
141             ## build an array of sources by target
142             ## its the reverse way to see what sources wants
143             ## to inject a target
144 0           foreach my $method (@$functions) {
145 0   0       $sources_by_target->{$target}->{$method} ||= [];
146 0           push @{ $sources_by_target->{$target}->{$method} }, $source;
  0            
147             }
148              
149              
150            
151            
152            
153            
154             } # end each $source
155            
156              
157             ## sorting the source by its priority
158 0           foreach my $target (keys %{ $sources_by_target }){
  0            
159 0           foreach my $method (keys %{ $sources_by_target->{$target} }){
  0            
160              
161 0           my @tosortarray = @{ $sources_by_target->{$target}->{$method} };
  0            
162             # @tosortarray = sort { $col->{$b}->{'priority'} <=> $col->{$a}->{'priority'} } @tosortarray;
163 0           @tosortarray = sort { $col->{$a}->{'priority'} <=> $col->{$b}->{'priority'} } @tosortarray;
  0            
164              
165 0           $sources_by_target->{$target}->{$method} = \@tosortarray;
166              
167             }
168             }
169            
170            
171             # print Dumper($sources_by_target);exit;
172              
173              
174              
175             ## collects replace tags for target.
176             ## if there is at least one class which wants
177             ## to replace the target, it will not keep the
178             ## original target method.
179 0           my $replace_target={};
180 0           foreach my $target (keys %{ $sources_by_target }){
  0            
181 0           foreach my $method (keys %{ $sources_by_target->{$target} }){
  0            
182              
183 0           foreach my $source ( @{$sources_by_target->{$target}->{$method}} ){
  0            
184            
185 0 0         if ( $col->{$source}->{'replacetarget'} ){
186 0           $replace_target->{$target} = 1;
187             }
188              
189             }
190             }
191             }
192              
193              
194            
195            
196             ## building the injection code
197 0           my @cmd;
198 0           foreach my $target (keys %{ $sources_by_target }){
  0            
199              
200 0           foreach my $method (keys %{ $sources_by_target->{$target} }){
  0            
201              
202 0           my $returntype = 'array';
203 0           my $returnmethod = 'last';
204              
205 0           my @cmd_pos;
206             my @cmd_neg;
207 0           my @cmd_zer;
208              
209              
210 0           push @cmd, ' my $orgm=\&'.$target.'::'.$method.';';
211              
212             # push @cmd, '*'.$target.'::_INJBAK_'.$method.'=\&'.$target.'::'.$method.';';
213              
214              
215 0           push @cmd, '*'.$target.'::'.$method.' = sub {';
216              
217 0           push @cmd, ' my @ret_org;';
218 0           push @cmd, ' my @ret;';
219 0           push @cmd, ' my @ret_refs;';
220 0           push @cmd, ' my @ret_last;';
221              
222 0           push @cmd, ' $__PACKAGE__::last_returned_value = [];';
223              
224              
225 0           push @cmd, 'do {'; # break block
226              
227            
228 0 0         if (!$replace_target->{$target}){ ## if no replace, reimplement original method
229 0           push @cmd_zer, ' @ret_org = &$orgm(@_);';
230              
231             # push @cmd_zer, ' @ret_org = '.$target.'::_INJBAK_'.$method.'(@_);';
232 0           push @cmd_zer, ' push @ret, @ret_org;';
233              
234 0           push @cmd_zer, ' push @ret_refs, \@ret_org;';
235              
236 0           push @cmd_zer,'last if $Class::Injection::break_flag;';
237              
238             }
239            
240 0           foreach my $source ( @{$sources_by_target->{$target}->{$method}} ){
  0            
241              
242 0           my $priority = $col->{$source}->{'priority'};
243 0           my $met_returntype = $col->{$source}->{'returntype'};
244 0           my $met_returnmethod = $col->{$source}->{'returnmethod'};
245            
246 0 0         if ($met_returntype) { ## a different returntype set?
247 0           $returntype = $met_returntype;
248             }
249              
250 0 0         if ($met_returnmethod) { ## a different returntype set?
251 0           $returnmethod = $met_returnmethod;
252             }
253              
254             #my $copymethod = $col->{$source}->{'copymethod'};
255              
256 0           my $waitcmd;
257 0           $waitcmd .= 'my @ret_tmp = '.$source.'::'.$method.'(@_);'."\n"; # method call
258              
259              
260 0           $waitcmd .= ' $__PACKAGE__::last_returned_value = \@ret_tmp;'."\n";
261              
262 0           $waitcmd .= ' push @ret_last, @ret_tmp;'."\n";
263 0           $waitcmd .= ' push @ret, @ret_tmp;'."\n";
264 0           $waitcmd .= ' push @ret_refs, \@ret_tmp;'."\n"; ## collecting references
265 0           $waitcmd .= ' last if $Class::Injection::break_flag;'."\n";
266            
267             ## depending on the priority place it before or after
268 0 0         if ($priority < 0){
269 0           push @cmd_neg, $waitcmd;
270             }
271              
272 0 0         if (0 < $priority){
273 0           push @cmd_pos, $waitcmd;
274             }
275            
276             }
277              
278 0           push @cmd, @cmd_neg;
279 0           push @cmd, @cmd_zer;
280 0           push @cmd, @cmd_pos;
281              
282             ## type of return - all the same at the moment
283 0           my $ret_sign='@';
284 0 0         if ( $returntype eq 'array' ){
    0          
    0          
285 0           $ret_sign = '@';
286             }
287             elsif ( $returntype eq 'scalar' ){
288 0           $ret_sign = '@';
289             }
290             elsif ( $returntype eq 'hash' ){
291 0           $ret_sign = '@';
292             }
293            
294            
295              
296             # what to return
297 0           my $ret_meth='ret';
298 0 0         if ( $returnmethod eq 'last' ){
299 0           $ret_meth = 'ret_last';
300             }
301 0 0         if ( $returnmethod eq 'all' ){
302 0           $ret_meth = 'ret';
303             }
304 0 0         if ( $returnmethod eq 'original' ){
305 0           $ret_meth = 'ret_org';
306             }
307 0 0         if ( $returnmethod eq 'collect' ){
308 0           $ret_meth = 'ret_refs';
309             }
310              
311 0           my $retv = $ret_sign.$ret_meth;
312              
313 0           push @cmd, '} until (1 == 1);'; # break block
314 0           push @cmd,'$Class::Injection::break_flag = 0;'; ## reset the break flag
315              
316 0 0         if ($returnmethod eq 'collect'){
317 0           push @cmd, ' return wantarray ? '.$retv.' : \\'.$retv.';'; ## assembles to a returnvalue
318             } else {
319 0           push @cmd, ' return wantarray ? '.$retv.' : shift '.$retv.';'; ## assembles to a returnvalue
320             }
321              
322             #push @cmd, ' return wantarray ? @ret : \@ret;' if $returntype eq 'array';
323            
324 0           push @cmd, '};';
325            
326              
327             } # end method
328             } ## end building injection code
329            
330            
331            
332 0           my $cmd = join("\n",@cmd);
333              
334              
335 0 0         if ($DEBUG){
336 0           print "sources by target:\n";
337 0           print Dumper($sources_by_target);
338             }
339              
340             ## save infos
341 0           $Class::Injection::info_store->{'sources_by_target'} = $sources_by_target;
342 0           _add_detailed_source_infos($sources_by_target);
343              
344              
345              
346 0 0         print "\n\n\n".$cmd if $DEBUG;
347            
348 0           eval($cmd);
349 0 0         if ($@){
350 0           die __PACKAGE__." ERROR when injecting: ".$cmd.$@;
351             }
352              
353             }
354              
355              
356              
357             ## Can be called inside a new method to get the value of a previosly called method.
358             ## It is allways an arrayref
359             sub lastvalue{
360 0   0 0 1   my $v = $__PACKAGE__::last_returned_value || [];
361 0           return $v;
362             }
363              
364              
365              
366             ## add some more infos to the info store,
367             ## call the method Class::Injection::info for all
368             ## infos.
369             sub _add_detailed_source_infos{
370              
371 0     0     my $detailhash = {};
372              
373 0           my $sinfo = $Class::Injection::info_store->{'sources_by_target'};
374              
375             ## adding detailed source infos (calling parameters)
376 0           foreach my $target (keys %$sinfo) {
377 0           foreach my $tmethod (keys %{ $sinfo->{$target} } ) {
  0            
378              
379 0           my @sdclass;
380 0           foreach my $sclass (@{ $sinfo->{$target}->{$tmethod} } ) {
  0            
381              
382 0           my $param = $__PACKAGE__::collector->{$sclass};
383              
384 0           push @sdclass,{ class=>$sclass, param=>$param };
385              
386             }
387 0           $detailhash->{$target}->{$tmethod}= \@sdclass;
388              
389             }
390             }
391            
392              
393 0           $Class::Injection::info_store->{'sources_by_target_detail'} = $detailhash;
394              
395 0           my @neg;
396             my @pos;
397              
398             ## building a replacement matrix as array
399 0           my @allmatrix;
400 0           foreach my $target (keys %$sinfo) {
401              
402 0           my $replacetarget;
403              
404 0           foreach my $tmethod (keys %{ $sinfo->{$target} } ) {
  0            
405              
406 0           my @matrix;
407              
408 0           foreach my $sclass (@{ $sinfo->{$target}->{$tmethod} } ) {
  0            
409              
410 0           my $param = $__PACKAGE__::collector->{$sclass};
411              
412 0   0       my $priority = $param->{'priority'} || 1; ## default is add
413              
414 0 0         if ($param->{'replacetarget'}){ $replacetarget=1 };
  0            
415              
416 0           my $node = {
417             target => "$target"."::$tmethod",
418             source => "$sclass"."::$tmethod",
419             comment => "injected",
420             };
421              
422 0 0         if ( $priority < 0 ){
423 0           push @neg, $node;
424             }else{
425 0           push @pos, $node;
426             }
427              
428              
429             }
430              
431 0           my $org = {
432             target => "$target"."::$tmethod",
433             source => "$target"."::$tmethod",
434             comment => "original",
435             };
436              
437 0           push @matrix,@neg;
438 0 0         push @matrix,$org if !$replacetarget;
439 0           push @matrix,@pos;
440              
441 0           push @allmatrix,\@matrix;
442              
443             }
444              
445              
446             }
447              
448              
449 0           $Class::Injection::info_store->{'replacement_matrix'} = \@allmatrix;
450              
451             }
452              
453              
454             ## Shows a easy to read matrix which methods injected which classes.
455             ## It displays also the new order of the methods.
456             sub show_replacement_matrix{
457              
458 0     0 1   my $matrix = $Class::Injection::info_store->{'replacement_matrix'};
459              
460 0           my @rows;
461              
462 0           foreach my $classblock (@$matrix) {
463              
464 0           my @crows;
465              
466 0           foreach my $methodblock (@$classblock) {
467 0           push @crows, sprintf("%-42s <- %-42s%-10s", $methodblock->{'target'}, $methodblock->{'source'}, $methodblock->{'comment'} );
468             }
469              
470 0           push @rows, join("\n",@crows);
471             }
472              
473 0           my $delim;
474 0           $delim.="-" x 100;
475 0           $delim.="\n";
476              
477 0           print $delim.join($delim,@rows)."\n".$delim."\n";
478              
479             }
480              
481              
482             ## sets a flag to break after current method. No further methods used in the method stack.
483             ## You can use that in your new method like:
484             ##
485             ## Class::Injection::break;
486             ##
487             sub break {
488 0     0 1   $Class::Injection::break_flag = 1;
489             }
490              
491              
492             ## returning infos about the installed methods as a hash.
493             sub info {
494 0     0 1   return $Class::Injection::info_store;
495             }
496              
497              
498              
499              
500              
501             1;
502              
503              
504              
505             #################### pod generated by Pod::Autopod - keep this line to make pod updates possible ####################
506              
507             =head1 NAME
508              
509             Class::Injection - Injects methods to other classes
510              
511             =head1 DESCRIPTION
512              
513             The Injection class is a elegant way to manipulate existing classes without editing them.
514             It is done during runtime. It is a good way to write plugins without creating special plugins
515             technologies.
516              
517              
518              
519             =head1 SYNOPSIS
520              
521              
522              
523             # Here an original class
524             # Imagine you want to overwrite the test() method.
525              
526             package Foo::Target;
527              
528             sub test{
529             my $this=shift;
530            
531             print "this is the original method.\n";
532            
533             }
534              
535              
536             In a simple Perl file you can use that class:
537              
538             use Foo::Target;
539              
540             my $foo = Foo::Target->new();
541              
542             my $foo = Over->new();
543              
544             $foo->test(); # outout is: 'this is the original method'
545              
546              
547             So far nothing happened
548              
549             If you want to change the test() method without editing the original code, you can use Class::Injection.
550             First create a new class, like this:
551              
552             package Bar::Over;
553              
554              
555             use Class::Injection qw/Foo::Target/; # define the target
556              
557              
558             sub test {
559             my $this=shift;
560              
561             print "this is the new method\n";
562            
563             }
564              
565              
566             To define the class which should be overwritten, you set the name after the 'use Class::Injection' call, here Foo::Target.
567              
568             In the calling Perl script to need to initialize that:
569              
570              
571             use Foo::Target;
572             use Bar::Over1;
573              
574             Class::Injection::install(); # installs the new methods from Bar::Over
575              
576             my $foo = Foo::Target->new();
577            
578             $foo->test(); # Output is: 'this is the new method'
579              
580            
581             The example above uses the default copymethod 'replace', which just replaces the methods.
582             Class::Injection can do more complicated things, depending on your need you can stack methods
583             to run several different variations e.g. of a test(). You can also define the way of returning a value.
584              
585              
586              
587              
588              
589              
590              
591              
592             =head1 ADD A METHOD
593              
594              
595             The simplest way to add a method to an existing one you can see in the example below. To add a method means to
596             execute the original method and the new method.
597              
598             package Over;
599              
600             use Class::Injection qw/Target add/;
601              
602             sub test { ... };
603              
604             This example overwrites a class 'Target'. You can see the second value after the target class is the copymethod.
605             Here it is 'add'. It is equivalent to 'append'.
606              
607              
608              
609              
610              
611             =head1 RETURN TYPES
612              
613              
614             You can configure the return types of a method. Please be aware of the its behaviours:
615              
616             1. It is a class-wide configuration.
617              
618             2. If you use more than one overwriting class, The last called, defines the overwriting rules.
619              
620             At first have a look into the following example how to set complex parameters:
621              
622             use Class::Injection 'Target', {
623             'how' => 'add',
624             'priority' => 4,
625             'returnmethod' => 'collect',
626             };
627              
628             The first parameter is still the target class, but then follows, seperated by a comma, a hashref with some values.
629              
630             how - defines the way of adding the method. Default is 'replace'. You can also use 'add' (same as 'append') or 'insert'.
631              
632             copymethod - same as 'how'.
633              
634             priority - please see the chapter PRIORITY for that.
635              
636             returns - defines the return-type. (see below)
637              
638             returntype - same as 'returns'.
639              
640             returnmethod - defines which method(s) return values are used. (see below)
641              
642             debug - enables the debug mode and prints some infos as well as the virtual commands. use 'true|yes|1' as value.
643              
644             replace - will cause the original method not to be used anymore, it will completely replaced by the injection methods. use 'true|yes|1' as value.
645              
646              
647             The returntype is currently set to 'array' for any type. What means it is not further implemented to returns something else.
648             I have to see if there changes are neccessary during praxis. So far it looks like a return of array is ok.
649              
650             The returntype is currently more automatically defined by context! It means if you e.g. call a
651              
652             my @x = test();
653              
654             It gives you an array, and if you do
655              
656             my $x = test();
657              
658             It gives you an scalar. But it depends on the used 'returnmethod' what exaclty you will get! With 'collect' it returns an
659             arrayref, with anything else it will be the first value, if in scalar context.
660              
661              
662              
663              
664              
665              
666              
667             =head1 RETURNMETHOD
668              
669              
670             The returnmethod can have the following values:
671              
672             last, all, original, collect.
673              
674             Before you start dealing with returnmethods, please note, that it might get compilcated, because you are changing the way of
675             returning values of the original method. If you just use 'replace' you dont change the returnmethods. It can be used to build
676             a plugin system and handling the results of several parallel classes.
677              
678             If you want to manipulate values with the methods (functions), I recommend using references as a part of the given
679             parameters and not the output of a method. For example:
680              
681             # not good:
682             my $string = 'abcdefg';
683             my $new_string = change_text($stgring)
684              
685             The example above will make trouble if you use 'collect' as returnmethod.
686              
687             # better:
688             my $string = 'abcdefg';
689             change_text(\$stgring)
690              
691             Here each new installed method just takes the reference and can change the text. No return values needed.
692              
693              
694             The default is 'last', what means the last called method's return values are used. This is the most save
695             way to handle, because this method is usually used somewhere already and a specific returntype is expected.
696             If you just change it, maybe the code stops working.
697              
698             Also save is 'orginal' that will just return the original's method value.
699              
700             With 'all' it merges all return values into an array, what must be handled in context. If you previosly used that call:
701              
702             my $x = test();
703              
704             It will give you now only the first value, what is maybe not what you want. Expect with 'all' an array as return value and handle it:
705              
706             my @x = test();
707              
708              
709              
710              
711             =head1 PRIORITY
712              
713              
714             You can add more than one method. To finetune the position, you can set as a third value a priority. The original
715             class has the priority 0. Every positive number comes later and negative numbers before.
716              
717             package Over;
718              
719             use Class::Injection qw/Target add -5/;
720              
721             sub test { ... };
722              
723             If you dont care about a priority, but just want the same order like it is listed, you can use 'insert' (before) or
724             'append'.
725              
726             use Class::Injection qw/Target append/;
727             ...
728             use Class::Injection qw/Target insert/;
729              
730             Inserted class's method will be called before the appended class's method.
731              
732              
733              
734              
735             =head1 PLUGINS
736              
737              
738             How to use Class::Injection to build a plugin system?
739              
740             I see two type of plugins here:
741              
742             1. Just replacing existing methods and returning ONE value, like the original method.
743              
744             2. The caller expects plugins, what means he may handle different return values, that can occour when e.g. used 'collect' as
745             a copymethod.
746              
747             For both types you will need to scan a folder for perl modules and 'use' them. Of course I assume they have the Class::Injection in use.
748              
749             If the calller expects plugins, I recommend using an abstract class as a skelleton, which the caller uses to instantiate the class.
750             The methods of the abstract class should already return an arrayref. And in the plugins use the key " replace => 'true' " in the
751             Class::Injection line. That will overwrite the abstract class's methods.
752              
753             package Abstract;
754              
755             sub test{
756             my $this=shift;
757              
758              
759             return [];
760             }
761              
762             1;
763              
764              
765             Here a plugin:
766              
767              
768             package Plugin1;
769            
770             use base 'Abstract';
771            
772             use Class::Injection 'Abstract', {
773             'how' => 'add',
774             'returnmethod' => 'collect',
775             'replace' => 'true',
776             };
777            
778             sub test{
779             my $this=shift;
780            
781             return "this is plugin 1";
782             }
783            
784             1;
785              
786             The main script:
787              
788             eval('use Plugin1;'); # only to show it might be dynamically loaded
789              
790             use Class::Injection;
791             use Abstract;
792              
793             Class::Injection::install();
794              
795             my $foo = Abstract->new();
796              
797              
798              
799              
800              
801              
802              
803              
804              
805              
806              
807              
808             =head1 FUNCTIONS
809              
810              
811            
812              
813              
814              
815             =head2 import
816              
817             Class::Injection::import();
818              
819             The import function is called by Perl when the class is included by 'use'.
820             It takes the parameters after the 'use Class::Injection' call.
821             This function stores your intention of injection in the static collector
822             variable. Later you can call install() function to overwrite or append the methods.
823              
824              
825              
826             =head2 break
827              
828             Breakig in a method
829              
830             Class::Injection::break();
831              
832             sets a flag to break after current method. No further methods used in the method stack.
833             You can use that in your new method.
834              
835              
836             If you want to break and makes the current method to the last one used, you can set a break flag by calling a static method:
837              
838             sub test{
839             my $this=shift;
840              
841             Class::Injection::break;
842              
843             return "this is plugin 1";
844             }
845              
846             After this method, nur further method is called. Make sure you use the break on the very and of a method, because it could be that further, deeper methods you
847             call, also are injected. That would cause a break for them.
848              
849              
850              
851              
852             =head2 lastvalue
853              
854             Value of last method
855              
856             If you want to work with the result of the former injected method in a method, you can get the
857             result, as a arrayref, with the static method lastvalue:
858              
859             Class::Injection::lastvalue
860              
861              
862              
863             =head2 info
864              
865             Class::Injection::info();
866              
867             returning infos about the installed methods as a hash.
868              
869              
870              
871             =head2 show_replacement_matrix
872              
873             Class::Injection::show_replacement_matrix();
874              
875             Prints an easy to read matrix like that:
876              
877             ----------------------------------------------------------------------------------------------------
878             Local::Abstract::test <- Local::Plugin2::test injected
879             Local::Abstract::test <- Local::Abstract::test original
880             Local::Abstract::test <- Local::Plugin1::test injected
881             ----------------------------------------------------------------------------------------------------
882              
883             to show what happens to the classes and methods.
884              
885              
886              
887             =head2 install
888              
889             Class::Injection::install();
890              
891             Installs the methods to existing classes. Do not try to call this method in a BEGIN block,
892             the needed environment does not exist so far.
893              
894              
895              
896              
897             =head1 REQUIRES
898              
899             L
900              
901             L
902              
903              
904              
905              
906              
907             =head1 AUTHOR
908              
909             Andreas Hernitscheck ahernit(AT)cpan.org
910              
911              
912             =head1 LICENSE
913              
914             You can redistribute it and/or modify it under the conditions of LGPL and Artistic (What means to keep the original author in the source code).
915              
916             =cut