Re: [PHP-DEV] [VOTE][RFC] Closure::call()

[email protected] (Andrea Faulds)
Newsgroups php.internals
Message-ID <[email protected]>
On 17 Aug 2014, at 22:36, Levi Morrison <[email protected]> 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 <[email protected]> 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/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.