Re: [ZEND-ENGINE-CVS] cvs: ZendEngine2 / zend_closures.c zend_closures.h zend_object_handlers.c /tests closure_033.phpt closure_034.phpt

[email protected] (Dmitry Stogov) Mon, 12 Jan 2009 10:34:26 +0300
Newsgroups php.zend-engine.cvs
Message-ID <[email protected]>
Marcus,

The current implementation conforms to http://wiki.php.net/rfc/closures

[see below]

Marcus Boerger wrote:
> Hello Dmitry,
> 
>   make your closure a static closure.
> 
> Without the current behavior we get even funnier things. And I am not
> sure all works as necessary yet. Suppose you have:
> 
> class Test {
>   functon __construct() {
>     $this->closure = function () {}
>   }
> }
> 
> Now Test::closure is bound to $this for each object.
> 
> How about:
> 
> $obj1 = new Test;
> $obj2 = clone($obj1);
> 
> what is $obj->closure->this now?

Both $obj1->closure->this and $obj2->closure->this are the same $obj1.

> Well it is of course wrong.

It is correct according to RFC (Interaction with OOP)

> I'll fix it.

It would be better to propose and explain what are you going to do
before implementing it.

> Oh and as always if you prefer broken behavior that confuses
> everyone....simply revert my stuff.

I prefer behavior that what discussed and agreed. In case we are going
to extend it, we should discuss it first.

I personally don't see an easy way which allows usage of closures for
extending objects with additional methods. However, if you make complete
solution I may change my mind or majority may vote for it.

Anyway, I would prefer to revert this patch for now.

Thanks. Dmitry.

> marcus
> 
> Sunday, January 11, 2009, 4:56:21 PM, you wrote:
> 
>> Even if it's cool, it may be problematic for many people who may break
>> their closures by assigning them to property.
> 
>> It's unclear for me way the following code changes the closure (rebind
>> it to become a method of $obj).
> 
>> <?php
>> $obj->prop = $closure;
>> $closure = $obj->prop;
> ?>>
> 
>> I afraid it just disallows assignment of closures to properties in a way
>> they were designed.
> 
>> Thanks. Dmitry.
> 
>> Marcus Boerger wrote:
>>> Hello Dmitry,
>>>
>>>   no I mean what the general technology, referred to as prototyping
>>> requires. What in general someone expects when binding a function
>>> to an object. Whether that is what JS does I couldn't count less.
>>> Though on the other hand it is the only prototype language that I
>>> use. Oh and continuing that thought, once again doing something in
>>> a way they know already is a pretty cool trick.
>>>
>>> marcus
>>>
>>> Sunday, January 11, 2009, 2:48:29 PM, you wrote:
>>>
>>>> Do you mean JavaScript like tricks which allow to create new methods by
>>>> assigning closures to object properties?
>>>> As I remember, it was decided not to support it.
>>>> Thanks. Dmitry.
>>>> Marcus Boerger wrote:
>>>>> Hello Dmitry,
>>>>>
>>>>>   it's what prototyping requires. I just made this behave as expected.
>>>>>
>>>>> marcus
>>>>>
>>>>> Sunday, January 11, 2009, 9:09:14 AM, you wrote:
>>>>>
>>>>>> Hi Marcus,
>>>>>> I'm wondered where this behavior comes from (It was never proposed or
>>>>>> may be I missed it).
>>>>>> Now, the simple assignment of closure to property and back changes its
>>>>>> internal $this pointer.
>>>>>> As result the following example is broken.
>>>>>> <?php
>>>>>> class A {
>>>>>>         private $a = 0;
>>>>>>         public $bar;
>>>>>>         function foo() {
>>>>>>                 return function() {
>>>>>>                         return $this->a++;
>>>>>>                 };
>>>>>>         }
>>>>>> }
>>>>>> class B {
>>>>>>         public $bar;
>>>>>>         function foo($a) {
>>>>>>                 return $a->foo();
>>>>>>         }
>>>>>> }
>>>>>> $a = new A;
>>>>>> $b = new B;
>>>>>> $f1 = $a->foo();
>>>>>> $f2 = $b->foo($a);
>>>>>> var_dump($f1());
>>>>>> var_dump($f1());
>>>>>> var_dump($f2());
>>>>>> var_dump($f2());
>>>>>> var_dump($f1());
>>>>>> $a->bar = $f1;
>>>>>> $b->bar = $f2;
>>>>>> $f1 = $a->bar;
>>>>>> $f2 = $b->bar;   // REASON OF THE BUG
>>>>>> var_dump($f1());
>>>>>> var_dump($f1());
>>>>>> var_dump($f2()); // BUG
>>>>>> var_dump($f2());
>>>>>> var_dump($f1());
>>>>> ?>>
>>>>>
>>>>>> Thanks. Dmitry.
>>>>>> Marcus Boerger wrote:
>>>>>>> helly         Sat Jan  3 17:46:25 2009 UTC
>>>>>>>
>>>>>>>   Added files:                 
>>>>>>>     /ZendEngine2/tests        closure_033.phpt closure_034.phpt 
>>>>>>>
>>>>>>>   Modified files:              
>>>>>>>     /ZendEngine2      zend_closures.c zend_closures.h zend_object_handlers.c 
>>>>>>>   Log:
>>>>>>>   - Rebind closure when binding to property
>>>>>>>   
>>>>>>>
>>>>>
>>>>>
>>>>> Best regards,
>>>>>  Marcus
>>>>>
>>>
>>>
>>>
>>> Best regards,
>>>  Marcus
>>>
> 
> 
> 
> 
> Best regards,
>  Marcus
>