NAME
IOC::Proxy - Proxy for the IOC Framework
SYNOPSIS
use IOC::Proxy;
my $proxy_server = IOC::Proxy->new({
on_method_call => sub {
my ($proxy_server, $method_name, $method_full_name, $current_method_args) = @_;
warn ("Method '$method_name' called with args (" .
(join ", " => @{$current_method_args}) .
"), now passing call to '$method_full_name'");
}
});
$proxy_server->wrap($object);
# this now wraps the $object in a special proxy package
# which will intercept all it's calls, while still
# behaving exactly as if it was not proxied
$object->method();
# this will warn:
# Method 'method' called with args (Class::_::Proxy=HASH(0x859978)), now passing call to 'Class::method'
DESCRIPTION
This module is a base class for all your IOC::Proxy needs. It can be used on it's own or it can be subclassed.
The basic idea of the IOC::Proxy is that since we are using the IOC framework to create our object instances, we can do certain things to those instances which we would not easily be able to do otherwise. In this specific case we can wrap the service instance with an IOC::Proxy object and be able to capture calls to the service instance through our proxy. The simplest use for this is some kind of logging.
The IOC::Proxy object does everything within it's power to make sure that the proxy object can be used as a drop in replacement to the service instance. This means we do not impose our OO-style on you class nor do we mess with your class's symbol table, and we are as transparent as possible.
IOC::Proxy guts
All this is accomplished by the creation of a proxy package, which is just you package name followed by ::_::Proxy
, which inherits from your object's class. We then gather up all the methods of your class by performaing a depth-first search of the inheritance tree (just as perl would do) and we then install these methods into our proxy package. We also check to see if your class has overloaded the stringification operator (""
) and if not, we install our own which will remove all trace of the ::_::Proxy
package from the output, so when you stringify your object it will not show the proxy (unless you use overload::StrVal
).
Once our proxied package is all set up, we re-bless your object into the proxy package. One of the benefits of this is that we do not need to worry about the underlying reference type your class is implemented with, and all data storage in your instance is preserved without issue.
All this means that your proxied object will respond as expected to calls to isa
and can
(including UNIVERSAL::isa
and UNIVERSAL::can
), and since we use goto
all evidence of IOC::Proxy is removed from the output of caller
as well. It also respects AUTOLOAD
, DESTROY
and overloaded operations. And when your object is automatically stringified, it will not show the proxy either. There is only one place where IOC::Proxy will reveal itself, and that is with ref
. Short of overloading CORE::GLOBAL::ref
this could not be done.
METHODS
- new ($config)
-
This will construct a IOC::Proxy object, but do nothing with it. The
$config
option is an HASH ref, which can be used to store data with your proxied object since it will not actually be an instance of IOC::Proxy. The$config
hash can have anything in it you want, but IOC::Proxy will look for two specific keys; on_method_call and on_wrap which should contain subroutine references and which will get called withinonMethodCall
andonWrap
respectively. - wrap ($object)
-
This will wrap the
$object
given to it in a proxy package as described in the "IOC::Proxy guts" section above. The return value of this method is the proxied object. Theoretically since we actually will re-bless$object
you don't actually need to capture that return value since the changes should affect$object
as well. - onWrap ($unwrapped_object, $proxy_package)
-
This method is here mostly for subclasses of IOC::Proxy. It will be called when IOC::Proxy wraps an instance. Currently it will look for the value on_wrap in the
$config
passed to the constructor (see above for more details).The first argument,
$unwrapped_object
is the object to be proxied, the second argument$proxy_package
is the name of the package it will be proxied with. It is up to you what to do with them. - onMethodCall ($method, $original_method, $args)
-
This method is here mostly for subclasses of IOC::Proxy. It will be called when IOC::Proxy recieves a method call. Currently it will look for the value on_method_call in the
$config
passed to the constructor (see above for more details).The first argument,
$method
is the short (local) name of the method which has been called. The second argument$original_method
is the fully qualified name of the method which includes the package where it actually comes from (which in inheritance situations may not be the class of the original proxied object). The third argument$args
is a reference to the@_
array the method was called with.
TO DO
BUGS
None that I am aware of. Of course, if you find a bug, let me know, and I will be sure to fix it.
CODE COVERAGE
I use Devel::Cover to test the code coverage of my tests, see the CODE COVERAGE section of IOC for more information.
SEE ALSO
AUTHOR
stevan little, <stevan@iinteractive.com>
COPYRIGHT AND LICENSE
Copyright 2004-2007 by Infinity Interactive, Inc.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.