ensembl-hive  2.7.0
Proxy.pm
Go to the documentation of this file.
1 =head1 LICENSE
2 
3 See the NOTICE file distributed with this work for additional information
4 regarding copyright ownership.
5 
6 Licensed under the Apache License, Version 2.0 (the "License");
7 you may not use this file except in compliance with the License.
8 You may obtain a copy of the License at
9 
10  http://www.apache.org/licenses/LICENSE-2.0
11 
12 Unless required by applicable law or agreed to in writing, software
13 distributed under the License is distributed on an "AS IS" BASIS,
14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 See the License for the specific language governing permissions and
16 limitations under the License.
17 
18 =cut
19 
20 
21 =head1 CONTACT
22 
23  Please email comments or questions to the public Ensembl
24  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.
25 
26  Questions may also be sent to the Ensembl help desk at
27  <http://www.ensembl.org/Help/Contact>.
28 
29 =cut
30 
31 =head1 NAME
32 
34 
35 =head1 SYNOPSIS
36 
37  #Simple arounds logging proxy
38  package myproxy;
39  use base qw/Bio::EnsEMBL::Utils::Proxy/;
40  sub __resolver {
41  my ($invoker, $package, $method) = @_;
42  return sub {
43  my ($self, @args);
44  warn "Entering into ${package}::${method}";
45  my @capture = $self->$method(@args);
46  warn "Exiting from ${package}::${method}";
47  return @capture;
48  };
49  }
50 
51  1;
52 
53 =head1 DESCRIPTION
54 
55 This class offers Proxy objects similar to those found in Java's
56 C<java.lang.reflect.Proxy> object. This class should be overriden and
57 then implement C<__resolver()>. The C<__resolver()> method returns a
58 subroutine to the intended action which the proxy object installs into
59 the calling class' scope.
60 
61 All methods internal to the proxy are prefixed with a double underscore
62 to avoid corruption/intrusion into the normal public and private scope of
63 most classes.
64 
65 =head1 METHODS
66 
67 =cut
68 
69 package Bio::EnsEMBL::Utils::Proxy;
70 
71 use strict;
72 use warnings;
73 
74 use Bio::EnsEMBL::Utils::Exception qw/throw/;
75 
76 use vars '$AUTOLOAD';
77 
78 =head2 new
79 
80  Arg [1] : The object to proxy
81  Example : my $newobj = Bio::EnsEMBL::Utils::Proxy->new($myobj);
82  Description : Provides a new instance of a proxy
83  Returntype : Bio::EnsEMBL::Utils::Proxy the new instance
84  Exceptions : None
85  Caller : public
86  Status : -
87 
88 =cut
89 
90 sub new {
91  my ($class, $proxy) = @_;
92  my $self = bless({}, ref($class)||$class);
93  $self->{__proxy} = $proxy;
94  return $self;
95 }
96 
97 =head2 __proxy
98 
99  Example : -
100  Description : The proxy accessor
101  Returntype : Any the proxied object
102  Exceptions : None
103  Caller : -
104  Status : -
105 
106 =cut
107 
108 sub __proxy {
109  my ($self) = @_;
110  return $_[0]->{__proxy};
111 }
112 
113 =head2 isa
114 
115  Args : Object type to test
116  Example : $obj->isa('Bio::EnsEMBL::Utils::Proxy');
117  Description : Overriden to provide C<isa()> support for proxies. Will return
118  true if this object is assignable to the given type or the
119  proxied object is
120  Returntype : Boolean; performs same as a normal can
121  Exceptions : None
122  Caller : caller
123  Status : status
124 
125 =cut
126 
127 
128 sub isa {
129  my ($self, $class) = @_;
130  return 1 if $self->SUPER::isa($class);
131  return 1 if $self->__proxy()->isa($class);
132  return 0;
133 }
134 
135 =head2 can
136 
137  Args : Method name to test
138  Example : $obj->can('__proxy');
139  Description : Overriden to provide C<can()> support for proxies. Will return
140  true if this object implements the given method or the
141  proxied object can
142  Returntype : Code; performs same as a normal can
143  Exceptions : None
144  Caller : caller
145  Status : status
146 
147 =cut
148 
149 sub can {
150  my ($self, $method) = @_;
151  my $super_can = $self->SUPER::can($method);
152  return $super_can if $super_can;
153  my $proxy_can = $self->__proxy()->can($method);
154  return $proxy_can if $proxy_can;
155  return;
156 }
157 
158 =head2 DESTROY
159 
160  Example : -
161  Description : Provided because of AutoLoad
162  Returntype : None
163  Exceptions : None
164  Caller : -
165  Status : -
166 
167 =cut
168 
169 
170 
171 sub DESTROY {
172  # left blank
173 }
174 
175 =head2 AUTOLOAD
176 
177  Example : -
178  Description : Performs calls to C<__resolver()> and installs the subroutine
179  into the current package scope.
180  Returntype : None
181  Exceptions : Thrown if C<__resolver()> could not return a subroutine
182  Caller : -
183  Status : -
184 
185 =cut
186 
187 sub AUTOLOAD {
188  my ($self, @args) = @_;
189  my ($package_name, $method_name) = $AUTOLOAD =~ m/ (.*) :: (.*) /xms;
190  my $sub = $self->__resolver($package_name, $method_name, @args);
191  if(! $sub) {
192  my $type = ref $self ? 'object' : 'class';
193  throw qq{Can't locate $type method "$method_name" via package "$package_name". No subroutine was generated};
194  }
195  {
196  no strict 'refs'; ## no critic ProhibitNoStrict
197  *{$AUTOLOAD} = $sub;
198  }
199  goto &$sub;
200 }
201 
202 sub __resolver {
203  my ($self, $package_name, $method, @args) = @_;
204  #override to provide the subroutine to install
205  throw "Unimplemented __resolver() in $package_name. Please implement";
206 }
207 
208 1;
209 
210 __END__
Bio::EnsEMBL::Utils::Proxy
Definition: Proxy.pm:38
Bio::EnsEMBL::Utils::Proxy::isa
public Boolean isa()
Bio::EnsEMBL::Utils::Exception
Definition: Exception.pm:68
Bio::EnsEMBL::Utils::Proxy::new
public Bio::EnsEMBL::Utils::Proxy new()