Re: closures questions

From: Date: Tue, 22 Jul 2008 12:15:39 +0000
Subject: Re: closures questions
References: 1 2  Groups: php.internals 
Request: Send a blank email to internals+get-39180@lists.php.net to get a copy of this message
Hi Lukas,
1) Closures on class properties just don't work, the only way to do it is to do something like: $c = $a->b; $c(); Calling: $a->b(); will result in method A::B() does not exists.
Yes, that's expected behaviour (we had a few comments on this on the list). Compare this to, for example: function hello () { echo "Hello World!\n"; } $a->b = 'hello'; $c = $a->b; $a->b (); // undefined method $c (); // works But, as closures implement the __invoke method, it's possible to do this: $a->b->__invoke (); or, of course call_user_func ($a->b); (which works with all types of callbacks, even non-closures)
so do we even want the toString() method?
Personally, I don't care.
4) var_export() and Closures is useless
What would you suggest? Having var_export return the function body for the closures? But what about bound variables? Well, perhaps in the future you could even export all the bound variables. But for know to keep it simple I'd say it's best that closures can't be exported.
5) Its impossible to clone a closure using the cloning keyword: $a = function(){}; $b = clone $a;
That's intended behaviour. What would be the clone of a closure? Especially with bound variables? This would allow for all sorts of weird behaviour. Take, for example, the following: class Foo { private $someProperty; function getPrinter ($outputDevice) {
    return function ($text) use ($outputDevice) {
      $outputDevice->print ($this->someProperty, $text);
    };
} } How would you clone that? There are two bound variables in this closure: $this and $outputDevice. Do you clone them both? Do you clone only $this? Do you clone only $outputDevice? If you only clone the closure object itself, it won't change the behaviour from simply creating another reference to it... If one *really* needs a clonable *and* callable object, write a class that implements __clone and __invoke. Then the programmer can control the exact semantics. Everything else would simply be extremely confusing. And, if I take another language such as Python for example, there you can't clone closures either, y = copy.deepcopy (closure) returns the same object.
This makes it hard to make a copy of the closure because of objects always are passed by reference.
I guess this is a draw back from the OO approach (rather than the original resource approach), but solvable?
No, the original resource approach was just the same. A resource is basically an integer value which is then used to look up some specific data. You can't clone a resource either. Regards, Christian

« previous php.internals (#39180) next »