Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:80937 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 87970 invoked from network); 21 Jan 2015 14:59:46 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 21 Jan 2015 14:59:46 -0000 Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.176 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.212.176 mail-wi0-f176.google.com Received: from [209.85.212.176] ([209.85.212.176:41360] helo=mail-wi0-f176.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 7C/D7-49046-1EEBFB45 for ; Wed, 21 Jan 2015 09:59:46 -0500 Received: by mail-wi0-f176.google.com with SMTP id em10so17245061wid.3 for ; Wed, 21 Jan 2015 06:59:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:content-type; bh=rFsw+jZ1hSLNr9kX+/huD04MHyShIqDv317guyfeUro=; b=kE4WygOt77pqD9Fyeva+OjehKsGVHE+iunJ3obItVSLOsQqBlX6A6ulGMfaIv6KyF4 yhB5oqbkJZQtqommbNrk24YXEF0quSTHOTlwIqocOmth9HCL7Pmf0oMiqoys8CXKCJ/R P/QmhnNxp1dgZpXFVyPT4IN4CgA/8Qcoe0KuYSqRjz5vAZV2J7JvYMXSJtD0g93NHnVF ZTbBQomdWsVKY+OZ2daNNGDxDeo/Q7LCjN2KkjhjyTWAYZi4kkUdaMni6aC0v+D0U9KC bI8jhhmWqEgbmisHiq3QcZis6ixyWe07poecH89A6EbSmT3LDZ5GZ64S1VE7tJiw96a1 tofw== X-Received: by 10.180.37.77 with SMTP id w13mr58179430wij.66.1421852382075; Wed, 21 Jan 2015 06:59:42 -0800 (PST) Received: from [192.168.0.172] ([62.189.198.114]) by mx.google.com with ESMTPSA id hv5sm113546wjb.16.2015.01.21.06.59.40 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 21 Jan 2015 06:59:41 -0800 (PST) Message-ID: <54BFBEA7.1020302@gmail.com> Date: Wed, 21 Jan 2015 14:58:47 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 MIME-Version: 1.0 To: "internals@lists.php.net" References: <54B93AAD.6080308@gmail.com> In-Reply-To: Content-Type: multipart/alternative; boundary="------------090003080105020007010908" Subject: Re: [PHP-DEV] Fixing strange foreach behavior. From: rowan.collins@gmail.com (Rowan Collins) --------------090003080105020007010908 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Yasuo Ohgaki wrote on 21/01/2015 02:48: > > I don't think that's an either/or situation: in most cases, it > would be up to the user to create that independent iterator, > because there's no general algorithm for cloning one that the > engine could use. (Think of an iterator proxying a database > cursor, for instance - it could be rewindable directly, but > cloning it would imply issuing a new query to create a new cursor > with separate state.) So the engine needs to issue an error > telling the user that they're reusing an object in an dangerous > way. An extended interface could be created later for those cases > that can handle the situation, although I doubt it would be that > common a use case. > > > I think if users need nested database cursor based iterator or like, > they should create new iterator object by themselves. > i.e. User should have __clone() that opens new cursor. I agree, and that's why I think nesting should be disabled by default. It needs to be a run-time flag, as nesting could be arbitrarily indirect: function iterator_dump($iter) { foreach ( $iter as $x ) { var_dump($x); } } foreach ( $some_iterator as $foo ) { dump ( $foo ); iterator_dump( $some_iterator ); // ERROR: Iterator cannot be used within nested foreach loops. iterator_dump( clone $some_iterator ); // OK, up to creator of iterator to implement __clone() } Perhaps foreach ( $some_iterator as $foo ) { ... } should be translated something like this: - if check_foreach_flag( $some_iterator ) == 1 then raise error - set_foreach_flag( $some_iterator ) - if check_initialised( $some_iterator ) then $some_iterator->rewind() - (if rewind fails, raise error) --- perform loop until iterator exhausted or break statement encountered --- - clear_foreach_flag( $some_iterator ) Where check_initialised() is some way of checking if the iterator has emitted values somewhere else, so needs rewinding. Without that, you couldn't use foreach on any iterator that couldn't be rewound, which would be pretty useless. I've no idea how feasible such flags are in the current implementation, though. Regards, -- Rowan Collins [IMSoP] --------------090003080105020007010908--