File Coverage

blib/lib/Method/Extension.pm
Criterion Covered Total %
statement 23 23 100.0
branch 1 2 50.0
condition n/a
subroutine 7 7 100.0
pod 0 1 0.0
total 31 33 93.9


line stmt bran cond sub pod time code
1             #
2             # This file is part of Method-Extension
3             #
4             # This software is Copyright (c) 2015 by Tiago Peczenyj.
5             #
6             # This is free software, licensed under:
7             #
8             # The MIT (X11) License
9             #
10 1     1   21542 use 5.006;
  1         4  
11 1     1   4 use strict;
  1         2  
  1         28  
12 1     1   4 use warnings;
  1         5  
  1         61  
13             package Method::Extension;
14             {
15             $Method::Extension::VERSION = '0.1';
16             }
17              
18             # ABSTRACT: Method Extension port for perl
19              
20 1     1   713 use parent 'Attribute::Handlers';
  1         283  
  1         5  
21            
22             sub UNIVERSAL::ExtensionMethod : ATTR(CODE) {
23 1     1 0 1291 my ($package, $symbol, $referent, $attr, $data, $phase) = @_;
24 1 50       7 $data = [$data] unless ref $data eq 'ARRAY';
25 1         1 foreach my $item (@{$data}) {
  1         3  
26 1     1   20275 no strict 'refs';
  1         2  
  1         59  
27 1         2 *{$item} = $referent;
  1         6  
28             }
29 1     1   6 }
  1         2  
  1         4  
30              
31             1;
32              
33              
34             =pod
35              
36             =encoding UTF-8
37              
38             =head1 NAME
39              
40             Method::Extension - Method Extension port for perl
41              
42             =head1 VERSION
43              
44             version 0.1
45              
46             =head1 SYNOPSIS
47              
48             package Foo;
49             # no baz method
50             ...
51              
52             package Bar;
53              
54             use Method::Extension;
55              
56             sub baz :ExtensionMethod(Foo::baz) {
57             my ($self, ... ) = @_; # $self will be a Foo instance
58             return "Baz from extension method";
59             }
60             ...
61              
62             Foo->new->baz();
63              
64             =head1 DESCRIPTION
65              
66             One good definition of Method Extension can be found L.
67              
68             Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type. For client code written in C# and Visual Basic, there is no apparent difference between calling an extension method and the methods that are actually defined in a type.
69              
70             In other words, you can create, in C# for example, one subroutine and use a syntax sugar to invoke as a method. In other words, instead do this:
71              
72             my $foo = Foo->new;
73             baz( $foo );
74              
75             You can do:
76              
77             $foo->baz(); # magic!
78              
79             This is very useful when you deal with languages like C# or Java, when you have a very strict way for add behavior to one class (Java does not support multiple inheritance, for example).
80              
81             Of course, in Perl we have more tools. L/L Roles, for example, are a great way to extend one class ( and you can apply one role in runtime ).
82              
83             But I miss extension methods. Because it is a syntax sugar we do not change the original class, and there is no way to emulate this in Perl (maybe override the operator -> or using some dark magic).
84              
85             The solution is ugly: this package offer one L C and it allows to inject the subroutine in the specified package. It is not a B extension method but it is our first effort. It is important call the attribute with the package + the method name ( I loose the subroutine name when we real with attributes ).
86              
87             What we have: one attribute who helps to inject one subroutine in another package.
88              
89             What I want to do (future): one way to avoid inject the subroutine, just like the sugar:
90              
91             $object->extension_method( args... );
92              
93             became
94              
95             extension_method( $object, args... );
96              
97             Better:
98              
99             {
100             use Bar qw(baz);
101              
102             Foo->new->baz; # ok
103             }
104              
105             Foo->new->baz # method not found
106              
107             If someone has some idea to help me on this, please let me know.
108              
109             Ps: AUTOLOAD seems B ugly and intrusive too.
110              
111             =head1 NAME
112              
113             Method::Extension - easily extend existing packages using method extension
114              
115             =head1 ATTRIBUTES
116              
117             =head2 ExtensionMethod
118              
119             With this attribute we can insert one subroutine to one existing package.
120              
121             Usage: C.
122              
123             Example:
124              
125             package Bar;
126              
127             sub baz :ExtensionMethod(Foo::baz) {
128             ...
129             }
130              
131             This inject the method Bar::baz into Foo::baz.
132              
133             Important: you should not forget to rewrite the method name. We loose the subroutine name when we deal with attribute.
134              
135             The good point is: we can use a different name. And we can inject in multiple packages too if we pass an array.
136              
137             =head1 LICENSE
138              
139             The MIT License
140              
141             Permission is hereby granted, free of charge, to any person
142             obtaining a copy of this software and associated
143             documentation files (the "Software"), to deal in the Software
144             without restriction, including without limitation the rights to
145             use, copy, modify, merge, publish, distribute, sublicense,
146             and/or sell copies of the Software, and to permit persons to
147             whom the Software is furnished to do so, subject to the
148             following conditions:
149            
150             The above copyright notice and this permission notice shall
151             be included in all copies or substantial portions of the
152             Software.
153            
154             THE SOFTWARE IS PROVIDED "AS IS", WITHOUT
155             WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
156             INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
157             MERCHANTABILITY, FITNESS FOR A PARTICULAR
158             PURPOSE AND NONINFRINGEMENT. IN NO EVENT
159             SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
160             LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
161             LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
162             TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
163             CONNECTION WITH THE SOFTWARE OR THE USE OR
164             OTHER DEALINGS IN THE SOFTWARE.
165              
166             =head1 AUTHOR
167              
168             Tiago Peczenyj
169              
170             =head1 BUGS
171              
172             Please report any bugs or feature requests on the bugtracker website
173             L
174              
175             =head1 AUTHOR
176              
177             Tiago Peczenyj
178              
179             =head1 COPYRIGHT AND LICENSE
180              
181             This software is Copyright (c) 2015 by Tiago Peczenyj.
182              
183             This is free software, licensed under:
184              
185             The MIT (X11) License
186              
187             =cut
188              
189              
190             __END__