Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:128000 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 078B41A00BC for ; Fri, 11 Jul 2025 03:08:59 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1752203229; bh=d3ZaAKZtO5ZD8ygy1xTOq2pmIE9pAI9xEO9g9YSBhx4=; h=References:In-Reply-To:Reply-To:From:Date:Subject:To:Cc:From; b=JeGY9o50V/gV3V0+f5PD2MrKUfmq7EMDdsrtqND+dHUX8WNRtPErC7+XThSdoO9WR qrAzQfdWppk7o7l+3U++nUx5WLhMisAJNLFGyxn+sHNgEj04Tm8MtRJ54l12RUMFMR fDaGQ86zyVkxHS/adtvdHWtKyR+B1NJLfK0w9588uffxDZTVb5A88G5JQfO0j7dbKS U4OwmVEVJ78InfS/Vu+xEo6OKOR1DFJC94KnUnTSQyMAlqplTUiUdOVv7UReDcWtVx qwA6wW5ucCG24bzb1/Qp/b5W6GBgWtp9cz5nWXte3ZWeRhd/3K7Kmvnx0CHfO5Y1yn qXOA4gS0blWdg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 4B1FF180039 for ; Fri, 11 Jul 2025 03:07:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=-0.2 required=5.0 tests=BAYES_20,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, FREEMAIL_REPLYTO,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: Error (Cannot connect to unix socket '/var/run/clamav/clamd.ctl': connect: Connection refused) X-Envelope-From: Received: from mail-il1-f180.google.com (mail-il1-f180.google.com [209.85.166.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 11 Jul 2025 03:07:08 +0000 (UTC) Received: by mail-il1-f180.google.com with SMTP id e9e14a558f8ab-3dc9e7d10bdso5298255ab.2 for ; Thu, 10 Jul 2025 20:08:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1752203337; x=1752808137; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :reply-to:in-reply-to:references:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=A7+fpklXEBrbqUVs4JmdwhIg4QmaMwZBCU1r73UPbcQ=; b=fVE5xh2xBuSwRK/cC329LwBbhJv8uIPdlzr3gOlD3b3SnDLRIqOf7dYr40tj13kriT Z/s7D0KFzTDNRb6F8qQoMDmuYurkxtt/TxAXFIMDRWkhO4ocztSqSRyNQrZ3LGAIjWKr 1XOz6w4Z3xgUn4Av/mtoSbyR8nleIccyYw3RmRaSy7go3SsJOODV56QvOH9K/Bioj1kE Bpr57O/TwBptXCsnyBqqV/suySVc/Rp+Dok/ZSDMsUmkBlQEFIs6si8x52TO2VjKRTPg 5GhxAukvbDDULY3s5TioYa+5j9+d+Zj1jDIAo7HQe1wjE88xEBS+pyIyPgPFNDi/Cwg5 WM4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1752203337; x=1752808137; h=content-transfer-encoding:cc:to:subject:message-id:date:from :reply-to:in-reply-to:references:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=A7+fpklXEBrbqUVs4JmdwhIg4QmaMwZBCU1r73UPbcQ=; b=Pmc729KumanRathPyFfrHn149Hw75nRNrCXnh2Q7Rf84lURM0Z5xnDp9fIdIveBvil i8elwbeN3/1A34/t1oH76YVDu1Inai150qGkK4l9D0wzLA/5aai8ZmuWrL1Sjvn2/fjG O2phRf//RBJ4z584LVRisDtNH6i6fhjxT1mTFk59w/6qVwqEv9hlDfW34GqbVrOpCGpB NQdRN8lmbJb9fH/6kpNSNw7DSF8CwoCLzsg54OtdsJwOVyn/K4f6mZ2VKhfXwNZTZGMy UN92QZj2/iwz25RfudtkCUnhepAkBlYQIrnV+Eq62szUowMlX/RfrNXTUIkiFToBdkzO igtg== X-Gm-Message-State: AOJu0YyhbjwVbxQUvB7H+d/VW1l4igHF9XvqZJyH2d2tb8QtzOWXnYLg nxmxo51Ta+kxKk1Zj9gH6b1180+nfBpmvUPb+TTNgw7bZWvsjYekuH1iY3J3qUEW0a9d7AhSX3c I0zEeNb5Iq8HSL536h5FWMJymOLyc+TE= X-Gm-Gg: ASbGnctL0fWmrr6visqib8L713bLw6i+KX0EnHsRLtxU3cm2xdWdVecc4BaM+5kGSxM pTILtGivzJT64N9C66//onfeSjfb1mEou8R1frFswrifqcI4qAjepyZwAgx+K6q6AgkMnC2oO8x wIEjuwvloE+RqxN66x0aRwZkhpNswe8lbHvHh9pqeGLHHQ1DauWXfGHNInPVvX6p5jP6qZdt2kj 6PiiT73PE34+v1f90SZASX90GXGLSNir6BdWW9ozg== X-Google-Smtp-Source: AGHT+IGppPSrFT7wQUe9HU59JMepf4NVLCHnAyxS+8ifrGo942ujYUi5hSoTzfqrHgpSXHi7ABXHONtuSwGW5y/YHs0= X-Received: by 2002:a05:6e02:1a68:b0:3dc:8746:962b with SMTP id e9e14a558f8ab-3e253326d67mr20877015ab.15.1752203336745; Thu, 10 Jul 2025 20:08:56 -0700 (PDT) Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 References: <1e8634d7-ac1a-4025-b4e2-1948aabf5251@app.fastmail.com> <46857A6D-5EAF-44AF-A2DE-9B40AF8DE8C8@gmail.com> <41241c3d-a601-4fb8-9f32-976bea3b660e@app.fastmail.com> <922a21f4-c28c-4824-b1d6-0c53ae080ffb@app.fastmail.com> In-Reply-To: <922a21f4-c28c-4824-b1d6-0c53ae080ffb@app.fastmail.com> Reply-To: erictnorris@gmail.com Date: Thu, 10 Jul 2025 23:08:40 -0400 X-Gm-Features: Ac12FXyn9By20ch4imIq3tdHQGqdwvcKvVkToiB8W4cKnzlAmevVJpSHePJ6rSM Message-ID: Subject: Re: [PHP-DEV] [RFC] Readonly property hooks To: Larry Garfield Cc: php internals Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: eric.t.norris@gmail.com (Eric Norris) On Wed, Jul 9, 2025 at 1:50=E2=80=AFPM Larry Garfield wrote: > > On Wed, Jul 9, 2025, at 10:42 AM, Eric Norris wrote: > >> An init hook would be clearer, certainly, though it also has its own e= dge cases. Can you set something that has an init hook? What happens if t= here's both a get and init hook? These probably have answers that could be= sorted out, but that's a different question from "why the does = a readonly class forbid me using even rudimentary hooks???" > >> > >> I'd be open to a follow up RFC for an init hook, though I likely would= n't write it myself. But that's a different topic than what we're addressi= ng here. > >> > >> --Larry Garfield > > > > I'm not entirely sure I follow - it sounds like your email states that > > `readonly` should be interpreted as `writeonce`, which makes sense, > > but then why would an `init` hook not be the appropriate answer here? > > > > The two scenarios you listed (`set` hooks for validation and lazy > > computed properties) seem like they could be solved by allowing `set` > > hooks (everyone seems +1 to that), an `init` hook, and disallowing > > `get` hooks. It would sidestep the controversial nature of a `get` > > hook for the property. > > > > It feels to me like an init hook would be the more conservative > > approach, and would (I imagine) still allow for potential `readonly` > > engine optimizations like Tim pointed out. Once we allow `get` hooks, > > there's no going back. If we still needed to add `get` hooks in the > > future, it's not off the table. > > > > I don't know that I feel strongly here, but there does seem something > > intuitively off with allowing a get hook for a readonly (writeonce) > > property. > > Can an init hook reference itself, the way get and set can? I apologize for being ignorant here, but I'm not sure what you mean by "referencing itself". Do you mean the backing value? No, because the backing value is unset - this is the initialization (and in the case of readonly, this is the "writeonce"). > If there is both an init and set hook, what happens? Is it different if = set reads from itself than if it writes to itself? > > Should combining init and set be forbidden as confusing? I don't have strong feelings here, but I think this is solvable in a way that is consistent and unsurprising. If you set the value, the set hook triggers, if the set hook reads the value, it triggers the init hook, if it's readonly, this might trigger an error since the set hook would try to set it a second time. > Can you have both an init hook and a get hook? What happens then? I think, at least for readonly, you couldn't have an init hook and a get hook, since the main objection here is to having get hooks on readonly properties at all. On normal properties, I think that'd be okay? > I don't know the answer to any of those. We could probably collectively = figure out some answers to that in time, but that's a much larger lift than= either Nick or I have any interest in engaging in at this point, especiall= y when there is a reasonable solution right in front of us that is trivial = to implement. I guess I don't agree that this is a reasonable solution at the moment. I don't know that I think it's unreasonable, either, but something about it feels wrong to me. I agree with Tim that I think of readonly properties as guaranteeing the immutability of identity. Regarding the caching option suggested elsewhere, the semantics mentioned seem confusing to me. The body is called on subsequent gets, but only the value from the first get is returned? I would expect that would be very confusing to developers. If the body wasn't executed on subsequent invocations that might make more sense to me, but then the get hook essentially is an init hook, and why not call it as such. Also, just to throw the idea out there - maybe start with init hooks *only* for readonly properties? Is there something to this, especially if you consider "readonly" actually "writeonce"? Maybe this plus disallowing set hooks?