Re: [VOTE][RFC] Closure::call()
| From: | Andrea Faulds | Date: | Sun, 17 Aug 2014 21:59:05 +0000 |
| Subject: | Re: [VOTE][RFC] Closure::call() | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-76620@lists.php.net to get a copy of this message | ||
On 17 Aug 2014, at 22:36, Levi Morrison <levim@php.net> wrote:
> I have a small clarification question on the RFC: you are adding
> another parameter to bindTo which defaults to false, but I didn't
> quite understand the reasoning. Can you try explaining that to me in a
> different way?
I’ll give it a go.
Closures have a bound object and a scope. The bound object is whatever $this will be set to when
that closure is called. The scope is the class whose private variables can be seen by a closure.
->call() will call the closure and use its existing scope but the bound object will be what is
passed as its first parameter. ->call() doesn’t permit calling with a different scope.
This presents a conundrum, however, if you want to use ->call() with a closure and you want to
have a scope. Currently, ::bind() and ->bindTo() only permit two types of closures with scopes:
those that are static (can’t have $this bound) and those that have an object bound. This means to
create a closure with a scope that you can then use with ->call(), you’d have to make one with
a dummy object already bound. In most cases you can do this, but there are a few you can’t, and
it’s weird to have to bind an object when we’re not going to use it anyway as ->call() is
going to override it.
For this reason, a third parameter is added to ::bind() and ->bindTo() which makes it produce an
unbound, scoped closure rather than a static scoped closure if we don’t pass an object to be bound
and we specify a scope. The need for the third parameter is really just backwards-compatibility. At
the moment, if you pass NULL for the object to bind to and pass a class name for the scope, it’ll
make a static closure. We could change this and make it produce an unbound closure and add some
other mechanism to obtain a static closure, but that would break backwards-compatibility. For this
reason, we instead add a third parameter to say, yes, we do want an unbound closure. The same thing
is done internally too, with zend_create_closure_ex.
On 17 Aug 2014, at 22:55, Stas Malyshev <smalyshev@sugarcrm.com> wrote:
> Hi!
>
>> I have a small clarification question on the RFC: you are adding
>> another parameter to bindTo which defaults to false, but I didn't
>> quite understand the reasoning. Can you try explaining that to me in a
>> different way?
>
> Interestingly enough, the RFC doesn't even mention this change.
It does, but maybe you missed it. Under the Proposal section:
> To solve this, we relax the current invariant of scoped closures having to be bound, and add a
> new parameter to bind(To) to produce an unbound, scoped closure, like so:
--
Andrea Faulds
http://ajf.me/