In general, I think it would be nice to have something that does this for you, but I am not necessarily a fan of changing the meaning of instanceof.

That's a lot of boilerplate for each possible iteration. This is one reason
people like traits so much, as it's easier to just do automated copy/paste
than use the proper patterns.

Couldn't a dynamic trait be a better?  It would work like this:

trait SplDynamicProxyTrait {

  protected $proxyObject;

  // enumerate all public method with the following:
  public function $name($signature) {
    return $this->proxyObject::$name($signature);
  }

}

usage would then be the following:

class MyDecorator implements FooInterface {
  use SplDynamicProxyTrait; // compile time "code generation"
  public function __construct(Foo $foo) {
     $this->proxyObject = $foo;
  }
  // override trait
  public function method2($a) {
    if (!$this->hasCache('method2', $a)) {
      $ret = $this->proxyObject->method2($a);
      $this->setCache('method2', $a, $ret);
    }
    return $this->getCache('method2', $a);
  }
}


So, example code like:

class Foo {}
class Bar extends SplDecorator {}
$b = new Bar(new Foo);
var_dump($b instanceof Foo); // true

It also works with type hints:
function test(Foo $f) {}
test($b);

These would all still work, instanceof would actually be an instanceof though.

Now, there's a lot more to do (property cascading, interface validation,
etc), but the initial proof-of-concept is there.

What do you think? Is this a route that I should continue down? Or is there
something fundamental that I'm missing here? I know that Reflection,
get_interfaces(), etc would need to be updated to account for this.

Thoughts?

In the above scenario, we've reused traits and we haven't broken instanceof or the liskov principle (which basically your implementation does since SplDectorator bypasses all method signature checking until runtime).

Thoughts? :)

-ralph


--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to