Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:46120 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 43732 invoked from network); 20 Nov 2009 06:55:57 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 20 Nov 2009 06:55:57 -0000 Authentication-Results: pb1.pair.com smtp.mail=crocodile2u@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=crocodile2u@gmail.com; sender-id=pass; domainkeys=bad Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.220.227 as permitted sender) DomainKey-Status: bad X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: crocodile2u@gmail.com X-Host-Fingerprint: 209.85.220.227 mail-fx0-f227.google.com Received: from [209.85.220.227] ([209.85.220.227:41506] helo=mail-fx0-f227.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 21/05-04175-C7D360B4 for ; Fri, 20 Nov 2009 01:55:56 -0500 Received: by fxm27 with SMTP id 27so3365390fxm.23 for ; Thu, 19 Nov 2009 22:55:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:received:in-reply-to:references :date:message-id:subject:from:to:cc:content-type :content-transfer-encoding; bh=UVfGIa4qdeSdkd18qoivhHgz0fXbH9uSFoRxn8B6al8=; b=FipNQbZoTm9sgB8rNtPuP5NyCMa9/r/vGf6NTOgqqEvuqkfRrbNVjw0s1RZr/2mThD CJq7Pck/MZsaSwsXYSgb2CFFl5q8wEv57FxG0VTCj0bVEwrNpW9dFJOGfniiHh3pWOSS eEkNikypiZjk4ZPCU/ofeSQvdkoPTnKOzAiGg= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; b=NBLT/oqaSQnFmfxuxOW1NCXds7ssyt6zh9L/141u3bUUBqQo1XdpeQcuIMKaIPnUv+ LL/oE9z84+OdlTpgouH8bLu13/blMg7ydoQuZ/FJRxOUBrtVD56XC8PeRSDg3jWxop9T dhonLQElr1rLikr4v2h8etyU+4+1BD59gJeuw= MIME-Version: 1.0 Received: by 10.102.13.21 with SMTP id 21mr470256mum.100.1258700153195; Thu, 19 Nov 2009 22:55:53 -0800 (PST) In-Reply-To: References: <4B01A4C2.8030602@gmx.net> <4B0273E5.9000606@easyflirt.com> <4B02D7FA.3080206@easyflirt.com> Date: Fri, 20 Nov 2009 09:55:53 +0300 Message-ID: To: Jelrik van Hal Cc: internals@lists.php.net Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] Closures and $this From: crocodile2u@gmail.com (Victor Bolshov) Hello. Jelrik, I could easily show a real-world example where using $this in closures could help. Consider Person class which has to verify that email address is unique. Suppose we have validation code in a single place and filter_var_array() is used to check all the data: class Person { .. function validate() { filter_var_array(array( 'email' =3D> array('filter' =3D> FILTER_CALLBACK, 'callback' =3D> $this->getEmailValidator()) )); } private function getEmailValidator() { return function($email) { // here, $this->id property is used, not only $email argument } } } When $this is available in closures, everything is ok. When you don't have $this - you end up with messy decisions like: private function getEmailValidator() { $self =3D $this; return function($email) use ($self) { // here, $self->getId() method is used } } .. or: function validate() { filter_var_array(array( // $this->validateEmail() should be public - breaks encapsulation 'email' =3D> array('filter' =3D> FILTER_CALLBACK, 'callback' =3D> array($this, 'validateEmail') )); } Of course, this is a special case - but I could easily imagine ActiveRecord class in which validation is based on a similar approach. This is why $this in closures would be useful for me - however I definitely would like $this not to change ever. 2009/11/19 Jelrik van Hal : > Victor Bolshov wrote: >> >> Hi. >> >> Personally, I beleive that (A) approach is the best: "bind $this to >> the object scope at creation" and never change it, issue error when >> $this is used where not available. It also seems to me like this way >> it could be implemented with better performance, am I right? >> >> Dynamically changing $this introduces confusion. You can use >> $this->foo or $this->bar() inside a closure, but when $this >> dynamically changes - you cannot be sure that "foo" property or "bar" >> method is still there. Furthermore, dynamic approach introduces even >> more mess when thinking about availability of private/protected class >> members. >> >> Consider this code: >> >> class Foo { >> =A0private $closure; >> =A0function __construct() >> =A0{ >> =A0 =A0/* It seems natural to me that, doing this assignment from within= the >> class, >> =A0 =A0 =A0 one can use private members inside the closure */ >> =A0 =A0$this->closure =3D function() { $this->privateMethod(); }; >> =A0} >> =A0function setClosure($closure) >> =A0{ >> =A0 =A0$this->closure =3D $closure; >> =A0} >> =A0function getClosure() >> =A0{ >> =A0 =A0return $this->closure; >> =A0} >> } >> >> $foo =3D new Foo(); >> $foo->getClosure()->__invoke();// #CALL-1 >> $foo->setClosure(function() { >> =A0/* >> =A0But is it good to use private members here? It seems like it would >> break encapsulation, >> =A0and the information that the class was designed to hide - is now >> made available in public access, >> =A0although indirect. >> =A0*/ >> =A0$this->privateMethod(); >> }); >> $foo->getClosure()->__invoke();// #CALL-2 >> >> In the end, I would like PHP to issue error when $this is used in >> #CALL-2 but to continue working on #CALL-1. >> >> The (A) approach seems to me more predictable, more simple, it has >> less information the developer needs to keep in mind when using >> closures. >> >> 2009/11/17 Mathieu Suen : >>> >>> Chris Stockton a =E9crit : >>>> >>>> Hello, >>>> >>>> On Tue, Nov 17, 2009 at 2:59 AM, Mathieu Suen >>>> wrote: >>>>> >>>>> Christian Seiler a =E9crit : >>>>>> >>>>>> Hi, >>>>>> >>>>>> since a few months have passed since the last discussion on this top= ic >>>>>> and perhaps people had time to gather some experience with the curre= nt >>>>>> closure implementation in PHP 5.3 I'd like to restart the debate on >>>>>> $this in closures and object extension. >>>> >>>> I believe that (D) wins my vote, and it convinces me twice. Once >>>> because I believe it is the most intuitive for users (A), and twice >>>> because I believe it is also the most useful (C) for users. In my >>>> opinion It seems the most "PHP" way. >>>> >>>> -Chris >>>> >>> (D) is quite inconstant: >>> >>> $block =3D $foo->closur; >>> >>> $foo->closur(); >>> $block(); >>> >>> This would produce 2 different output. >>> For (C) here is my objection: >>> >>> Suppose that we are in a MVC pattern. >>> In a controller on could do: >>> >>> $model->onFailDo(function () {$this->reportError()}); >>> $model->save(); >>> >>> >>> In the model side: >>> >>> public function onFailDo($block) >>> { >>> =A0 =A0 =A0 $this->signalFailure =3D $block >>> } >>> >>> public function save() >>> { >>> =A0 =A0 =A0 //... Something wrong happen >>> =A0 =A0 =A0 return $this->signalFailure(); >>> } >>> >>> If you dynamically bind the $this you are obliged to treat the error >>> reporting in the model which is not a good idea. Even worst you can't >>> even >>> catch up the error in the controller. >>> It also mean that the closure is getting tightly coupled with anyone wh= o >>> is >>> using it. And passing closure to different object is like spreading >>> dependency over all the system. >>> >>> -- Mathieu Suen >>> >>> -- >>> PHP Internals - PHP Runtime Development Mailing List >>> To unsubscribe, visit: http://www.php.net/unsub.php >>> >>> >> > > Hi, > > Victor, I do wholeheartedly agree with you about the mess things will be > when allowing $this to refer to different things in different contexts of > calling the same closure (B, C and D): I think it'll prove very difficult= to > keep track of which call will end up doing exactly what in which > environment. > > What I'm not really aware of are any big advantages of rebinding $this to > the local environment of the calling code: isn't it just making $this/thi= ngs > unnecessarily difficult? > > Also, I'm wondering why people think there should be a $this inside a > closure. As stated in the RFC/Wiki, closures are not thought out to be us= ed > alongside OO-code. Why would we want to couple them? I see the use of > closures, but not as OO-related tools using $this. What is the problem wi= th > proposal (0), leaving it as it is now? > > -jelrikvh > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: http://www.php.net/unsub.php > > --=20 Regards, Victor