Excuse me a moment while I delve into complex OO. :-) I have an object to which I want to add behavior (methods). I cannot use inheritance here because the object is already of a type or subtype (vis, I am already using inheritance for something else), and because I want to be able to add multiple types of behavior at runtime. The normal OO response to this situation is the Decorator pattern. -------------------- interface F { function doStuff(); } class Foo { function doStuff() { ... } } class Decorator implements F { protected $foo; function __construct(Foo $foo) { $this->foo = $foo; } function doStuff() { $this->foo->doStuff(); } } class Bar extends Decorator { function doThings() { ... } } $f = new Foo(); $b = new Bar($f); $b->doStuff(); $b->doThings(); -------------------- OK, great, that's wonderful. You can also nest such decorators indefinitely, provided that they only override methods from Foo and change its behavior, then pass on up the chain. Neat. What you cannot do, however, is nest decorators that have public methods. That is: -------------------- class Baz extends Decorator { function doOtherThings(); } $f = new Baz(new Bar(new Foo)); $f->doOtherThings(); // Works. $f->doStuff(); // Works. $f->doThings(); // Fail. -------------------- Now, PHP does have a loophole around this problem in the form of __call(). Specifically, instead of Decorator wrapping each method of F/Foo directly it implements __call(): -------------------- class Decorator { protected $foo; function __construct(Foo $foo) { $this->foo = $foo; } function __call($method, $args) { return call_user_func_array(array($this->foo, $method), $args); } } -------------------- That should work and allow the code snippet above to run, but it has two significant problems: 1) Because Decorator does not directly implement F, you cannot use type hinting. 2) __call() and call_user_func_array() are both fairly slow operations, and stacking them then becomes a nightmare for performance. #1 can largely be solved by both directly implementing F *and* implementing __call(), but we're still left with the performance problems of #2. While for some uses cases that is OK, it can add up to unpleasant microseconds lost. Can anyone suggest an alternate solution that has less of a performance hit? -- Larry Garfield larry@xxxxxxxxxxxxxxxx -- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php