Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:88969 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 94989 invoked from network); 28 Oct 2015 16:46:28 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 28 Oct 2015 16:46:28 -0000 Authentication-Results: pb1.pair.com smtp.mail=rowan.collins@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=rowan.collins@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.212.179 as permitted sender) X-PHP-List-Original-Sender: rowan.collins@gmail.com X-Host-Fingerprint: 209.85.212.179 mail-wi0-f179.google.com Received: from [209.85.212.179] ([209.85.212.179:37788] helo=mail-wi0-f179.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 5C/D3-63642-0EBF0365 for ; Wed, 28 Oct 2015 11:46:25 -0500 Received: by wicfv8 with SMTP id fv8so20014744wic.0 for ; Wed, 28 Oct 2015 09:46:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-type:content-transfer-encoding; bh=XIGIlRHw3W2mKwgiDQsE8Ovx4Hw8Gm7CB8IhkQ0UVhA=; b=bNCokxVIw+IWjAoIekHAAh+2g+mEEhzwKRjYrOrQDb5T0evzKZu5bMhwTthRbmwcUD arKAjq7HpTsf7XD/fKfKz/SpedK9MIMFpDyZKaEY2nQ0B4gwGN61/qm8dyVTWe5sQZkc Gc/QRtCMIMyd+i8jHe8F6otCxXRiJShgr7gQGWsrahXEyAY3LCm6m6sDvJShrMudQ9ZZ IdvT139CypYVbYCitQkqrKOlV1TokTOmrYyiItWZpaoDbuH0J0lxXf+gklbUT1bFw3YH ySNFWn5D1MCRjC1OqgdnY/J9HL3s9NlzkV7+HuKf/oI/zC6PhWqtH+BUUF4yJH06UtBL JaLQ== X-Received: by 10.194.87.40 with SMTP id u8mr38590936wjz.121.1446050781747; Wed, 28 Oct 2015 09:46:21 -0700 (PDT) Received: from [192.168.0.143] ([93.188.182.58]) by smtp.googlemail.com with ESMTPSA id n17sm4949991wmg.17.2015.10.28.09.46.20 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Oct 2015 09:46:21 -0700 (PDT) To: internals@lists.php.net References: <5630DE79.8070205@gmail.com> Message-ID: <5630FBC1.4000806@gmail.com> Date: Wed, 28 Oct 2015 16:45:53 +0000 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.3.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] In a destructor, how to detect if an exception is currently in flight? From: rowan.collins@gmail.com (Rowan Collins) Erik van Velzen wrote on 28/10/2015 15:02: > The ScopeGuard's destructor can now detect the condition: > > if ( $this->success_registered ) { > // Function reached checkpoint for this scope > $this->callSuccessHandlers(); > } else { > // Function aborted early, due to a throw or early return > $this->callExitHandlers(); > } > $this->callExitHandlers(); > > > No boilerplate throw-catch needed, works even if there is already a catch or > finally within the function's definition. > > In fact, I kind of want to use this somewhere now... ;) On the downside, it's worth noting that while PHP destructors are technically deterministic, the language can actually prevent them running on scope exit, because Exceptions hold references to everything used as a parameter in their stack traces. In the below very simple example, both err() and foo() have completed, but the destructor fires only once the Exception is caught and discarded. So if you passed your ScopeGuard object around at all, you might find things executing in a surprising order. (Personally, I think this is bad behaviour, and have argued that Exceptions should not capture these references, but I haven't been able to convince anyone it's worth changing.) # https://3v4l.org/Kc9Ck class KillMe { public function __destruct() { echo 'Thank you!'; } } function err($ignored) { throw new Exception; } function foo() { $k = new KillMe; err($k); } try { foo(); } catch ( Exception $e ) { echo 'Handling error. Destructor has not yet fired. '; }