Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:53539 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 67363 invoked from network); 23 Jun 2011 15:28:03 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 23 Jun 2011 15:28:03 -0000 Authentication-Results: pb1.pair.com smtp.mail=neufeind@php.net; spf=unknown; sender-id=unknown Authentication-Results: pb1.pair.com header.from=neufeind@php.net; sender-id=unknown Received-SPF: unknown (pb1.pair.com: domain php.net does not designate 91.184.32.3 as permitted sender) X-PHP-List-Original-Sender: neufeind@php.net X-Host-Fingerprint: 91.184.32.3 mail.speedpartner.de Linux 2.5 (sometimes 2.4) (4) Received: from [91.184.32.3] ([91.184.32.3:38087] helo=mail.speedpartner.de) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id D6/B2-53684-28B530E4 for ; Thu, 23 Jun 2011 11:28:03 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by mail.speedpartner.de (Postfix) with ESMTP id 1E9E3B3C89 for ; Thu, 23 Jun 2011 17:28:00 +0200 (CEST) Received: from mail.speedpartner.de ([127.0.0.1]) by localhost (mail.speedpartner.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id d+fk6ez4fP+a for ; Thu, 23 Jun 2011 17:28:00 +0200 (CEST) Received: from collab.speedpartner.de (collab.speedpartner.de [91.184.32.10]) by mail.speedpartner.de (Postfix) with ESMTP id ED14FB3ABB for ; Thu, 23 Jun 2011 17:27:59 +0200 (CEST) Received: from localhost (localhost.localdomain [127.0.0.1]) by collab.speedpartner.de (Postfix) with ESMTP id E152BFF0003 for ; Thu, 23 Jun 2011 17:27:57 +0200 (CEST) X-Virus-Scanned: amavisd-new at collab.speedpartner.de Received: from collab.speedpartner.de ([127.0.0.1]) by localhost (collab.speedpartner.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kHDrUqw-C6dm for ; Thu, 23 Jun 2011 17:27:57 +0200 (CEST) Received: from sn-dell.local.neufeind.net (ip-62-143-29-72.unitymediagroup.de [62.143.29.72]) by collab.speedpartner.de (Postfix) with ESMTPSA id 05FE6FF0002 for ; Thu, 23 Jun 2011 17:27:57 +0200 (CEST) Message-ID: <4E035B7E.4010703@php.net> Date: Thu, 23 Jun 2011 17:27:58 +0200 User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.17) Gecko/20110428 Fedora/3.1.10-1.fc15 Thunderbird/3.1.10 MIME-Version: 1.0 To: internals@lists.php.net References: <4E0355AE.4080305@php.net> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] Variable scopes for language constructs (foreach, ...) From: neufeind@php.net (Stefan Neufeind) On 06/23/2011 05:17 PM, Anthony Ferrara wrote: > Personally, I don't care for the concept of a block scope. I do > understand that it can have benefits and make certain tasks easier. > But it can also lead to weird bugs and inconsistencies. For example, > take the following code: > > $good = false; > > foreach ($array1 as $value) { > $good = $good & $value; > } > > unset($good); > > foreach ($array2 as $value) { > $good = $value; > } > > var_dump($good); > > What's the value of the dump? Should it be null? Should it be the > last element of array2? Why? From my feeling it would be the present outside of the first foreach()-loop right before the unset() since the variable was created outside the foreach() already. Then it was unset (doesn't exist) and recreated inside the second foreach-loop. If you even wanted to explicitly say that you don't want to go for the outside-visibile $good then, as proposed, you could use some var $good; inside the foreach-loop imho to declare that you want a new variable only visible inside the block. When that ends the outside-visibile $good would be used again. In case of "clean programming" the $good before the first example would be there anyhow if somebody wants to rely on $good having a value after the first foreach(). > We now have the ability to close around scopes, so I fail to see the > reason to do this. If you want a separate scope, then do an extract > method on the loop. Pull it out to another method and be done. It'll > be cleaner anyway. Besides, if you buy the arguments made in most > clean code books, you shouldn't have more than 1 block in a single > function anyway (as then it starts to do too much). So the scoping > issue becomes pointless at that point. You can always argue that creating smaller methods (like "no methods with more than 100 lines" or so) would limit the problems of a forgotten (not unset()) reference-variable. But imho that's not the point. Kind regards, Stefan Neufeind > On Thu, Jun 23, 2011 at 11:09 AM, Ferenc Kovacs wrote: >> On Thu, Jun 23, 2011 at 5:03 PM, Stefan Neufeind wrote: >> >>> Hi, >>> >>> I've lately discussed with a colleague which scopes of variables exist >>> for PHP or would probably make sense. In general I think the general >>> idea of having variables available all throughout a function is okay as >>> this allows things like >>> >>> foreach($vals as $v) { >>> // ... >>> $found = true; >>> } >>> if($found) { >>> // ... >>> } >>> >>> (setting $found inside the loop while still being able to access it >>> outside) >>> >>> But the interesting part is that $v is also still available outside the >>> loop (last value). While most people would say this is not a big >>> problem, it can become problematic when using references. >>> >>> foreach($vals as &$temp) { >>> // ... >>> } >>> // ... >>> $temp = 5; >>> (when you don't think about the reference anymore but want some >>> temp-variable) >>> >>> >>> If this has been "throughly discussed" before, please excuse. But if not >>> maybe somebody could share his oppinion on the following proposal. >>> >>> What if we (for example with PHP 5.4 or if not possible maybe with the >>> next one) change the behaviour so that >>> >>> * variables used for key/value in foreach (probably other places?) would >>> be limited to that loop-scope >>> >>> and maybe >>> * variable $found in the first example would need to be initialised >>> before the loop. Otherwise it would be a new variable inside the scope >>> of foreach that would be gone afterwards >>> >>> and/or maybe >>> * allowing to explicitly limit variable-scopes inside blocks, for >>> example by allowing var $found somewhere inside a function to allow >>> things like >>> >>> if($a) { >>> var $temp; >>> >>> $temp = 5; >>> } >>> // and $temp would be gone here; was limited to the scope in which it >>> was defined by var >>> >>> >>> Hope this is not too much of a non-sense idea to you :-) >>> >>> >> Hi, >> >> it was discussed many times on the list, and this behavior is also >> documented, see >> http://php.net/manual/en/control-structures.foreach.php >> >> "Reference of a $value and the last array element remain even after the >> foreach loop. It is recommended to destroy it by unset()." >> >> personally I find that weird, and unintuitive, but changin that in a major >> or minor version could be changed if we chose to. >> >> Tyrael >> >