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 within onMethodCall and onWrap 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

Work on the documentation

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

Class::Proxy
Class::Proxy::Lite
Class::Wrap

AUTHOR

stevan little, <stevan@iinteractive.com>

COPYRIGHT AND LICENSE

Copyright 2004-2007 by Infinity Interactive, Inc.

http://www.iinteractive.com

This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.