Hello Internals, our new closures can easily work as prototypes and I actually thought of simply doing it as a bug fix. But it appeared that my first attempt was inclomplete if not to say completely wrong. It further more turned out that not everyone is a fan of the genral idea.
Basically what I expected is that closures assigned to object properties behave in the same way prototypes behave. That is: 1) a non static closure assigned to an instance changes the closures this to be set to the actual object: $closure = function() {} // $closure->this == NULL $obj1->property = $closure; // $obj1->property->this == $obj1; // $closure->this == NULL 2) a static closure assigned to an instance sets the closure's scope 1+2) both give access to private members 3) Assignment of a closure from one object property to another objects property changes it $this. $obj2->property = $obj1->property; // $obj1->property->this == $obj1 // $obj2->property->this == $obj2 4) Cloning an object assigns the properties correct. Right now we increase the refcount only instead of cloning as that is the default behavior of cloning. Since a normal variable splits on changes nothing ever notices this. For oject types that do not support cloning this is very different though. Now we cannot simply add cloning as then we'd further change closure behavior. And this way we would not fix the this pointer. $obj3 = clone $obj; // $obj3>property->this == $obj3 5) A closure assigned to a property can be called directly rather than just by a temporary variable: $obj->property = function() {} $obj->property(); // valid call The above requires the following internal modifications: 1) Closures internally support clone, but do not set the actual handler, thus preventing anything else from cloning them (current behavior). 2) Default object cloning does not only call add_ref per member variable but also checks for a member being a prototype method in which case it performs the necessary cloning of that property. 3) An additonal check in the default property get handler is reaquired to check for a closure property (prototype) in case a function cannot be found. Unless someone uses closures there will be no change in behavior. If this gets done later we will change behavior. Why did I work on this: 1) Because to me the current implementation is broken. While as closures themselves work perfect, they simply work very unexpected when assigned to an object. 2) The current behavior seems inconsistent as it matters where an assignment of a closure to a proeprty is being performed. OR how a closure is being created. 3) The current behavior can be used as an impleentation of prototype methods in PHP. However it just does a very tiny subset that makes it a broken implementation. So we will end up in a situation where users see prototype methods but don't get them to work. 4) We could finally get more consistency because we would have a partial protoype ojbect model not only for member variables but also for member functions. Issues that speak against this: 1) A closure bound to a property is case sensitive unlike a member function. We have this however anyway. As we already have functions callable by variables whether the variable is a closure or just a function name. 2) To close to a release. Well that's why we have beta cycles to identify tsituations like this. 3) If closures get callable by property directly then we end up in a situation where we can have two methods with the same name. That means it is discussable whether we want to allow assignment of a closure to a member variable name that already exists as a private member function. Best regards, Marcus -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php