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/