Re: [PHP] Generic decorators and type hinting

2009-09-02 Thread Ben Dunlap
> code.  Instead, just use interfaces.  The only real downside is that
> all the classes you want to decorate would need to implement them and
> that would cause a wee bit of ugliness in the code/class declaration.

Can you explain a bit more? As I understood the OP, the challenge was
to take a large, already-built code base that relies on Zend Framework
(which itself has 1600 classes), and wrap arbitrary existing methods
with timing logic -- without significant code changes.

As I understand your solution, it would require all pre-existing
classes to be modified to implement the iDecorator interface -- and
even then, pre-existing methods in those pre-existing classes would
not actually be affected. So those would have to be modified also.

But maybe I'm totally missing something?

Ben

--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Generic decorators and type hinting

2009-09-02 Thread Christoph Boget
> I have a possibly-evil idea that gets around type-hinting by
> dynamically declaring decorator classes as children of the real
> classes that need to be timed. You end up with as many "decorators" as
> you have classes that need to be timed, but if this is for dev/QA
> purposes only, that might not be a problem.

You don't even need to do that; it'd generate way too much redundant
code.  Instead, just use interfaces.  The only real downside is that
all the classes you want to decorate would need to implement them and
that would cause a wee bit of ugliness in the code/class declaration.
But if you are fine with that, it's a perfect solution, particularly
since you can type hint interfaces.

interface iDecorator {}

class Thing implements iDecorator {}

class Timer
{
  public static function time( iDecorator $obj ) {}
}

$obj = new Thing();
Timer::time( $obj ); // $obj becomes a Timer obj with $obj inside it
$obj->thingMethod(); // Timer passes call to Timer->obj

thnx,
Christoph

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP] Generic decorators and type hinting

2009-09-02 Thread David Kurtz

On Sep 2, 2009, at 12:17 PM, Ben Dunlap wrote:


I've got some sample code written that first calls get_class_methods()
to list the names of all the visible methods of the parent object,
then constructs code to declare a child class that overrides those
methods with wrapper methods, and finally eval()s the declaration and
instantiates an object of the new class.



You're right; that is evil.

But, interesting idea. It turns out for my specific purposes (a  
generic decorator that measures a class's method execution times), a  
full-fledged profiler like APD is really what I need, but I'll keep  
this in mind for getting around the type-hinting, should the need  
arise again.


Thanks.
--
David Kurtz
dku...@technorati.com





Re: [PHP] Generic decorators and type hinting

2009-09-02 Thread Ben Dunlap
> Is there another way to cleanly wrap method calls for timing/logging
> purposes?

I have a possibly-evil idea that gets around type-hinting by
dynamically declaring decorator classes as children of the real
classes that need to be timed. You end up with as many "decorators" as
you have classes that need to be timed, but if this is for dev/QA
purposes only, that might not be a problem.

This method can't have the conceptual simplicity of yours,
unfortunately, because __call() will never be invoked in a child
class. The original parent's methods will just be called instead. But
you can still override the parent's methods with wrapper methods in
the child class.

I've got some sample code written that first calls get_class_methods()
to list the names of all the visible methods of the parent object,
then constructs code to declare a child class that overrides those
methods with wrapper methods, and finally eval()s the declaration and
instantiates an object of the new class.

The basic concept seems to work and to get along fine with
type-hinting. I'm happy to share the test code if you're interested.
Not sure how it would end up working in real life, and I'm guessing
there are more sophisticated ways to achieve the same concept, perhaps
using the Reflection API. I suspect it also needs some refining to
handle protected methods. But it might be a start.

Ben

-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[PHP] Generic decorators and type hinting

2009-09-01 Thread David Kurtz
I'm looking for a way to implement a generic Timing class as a  
decorator or come up with a solution for timing code execution without  
cluttering the code.


In my web app, there is a perceived need to measure the execution time  
of many function calls and database queries using ZFDebug and its  
timing plugin.


An initial crack at this resulted in lots and lots of timing code  
interspersed with real code, which made modification and debugging a  
bit nightmarish.


As a solution, I wrote a very bare-bones Timing class, a decorator  
that would encapsulate an object, intercept calls to the object via  
the __call method, start a timer, pass the call through to the  
encapsulated object, then stop the timer.


My interface went like this:

$obj = new Thing();
Timer::time( $obj ); // $obj becomes a Timer obj with $obj inside it
$obj->thingMethod(); // Timer passes call to Timer->obj

This worked great (and if anyone's interested I can pass on the code)  
-- my timers worked, and the code originally written for $obj didn't  
even notice -- except in cases where a function used type hinting and  
I got Unknown errors. I'm using Zend Framework, and (for instance) I  
was curious about the timing on my Initializer (a controller plugin),  
so I thought the following would do the trick:


$initializer = new Initializer($env);
Timer::time( $initializer );
$frontController->registerPlugin( $initializer );

But machinery deep in the bowels of Zend does type hinting for a  
Zend_Controller_Plugin_Abstract object, not a Timer, and so an error  
is raised.


Whole point is that I want to be able to use this Timer class on  
anything. Seems like I should be able to if it weren't for the type  
hinting.


Is there any way to fool a function into thinking my Timer is the same  
class as Timer->obj?
Is there another way to cleanly wrap method calls for timing/logging  
purposes?
Any other good patterns for measuring code execution time without  
cluttering the code?


I found this discussion from last December, asking a very similar  
question, but it seemed unresolved:




--
David Kurtz
dku...@technorati.com




--
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php