Newsgroups: php.internals
Path: news.php.net
Xref: news.php.net php.internals:123371
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 qa.php.net (Postfix) with ESMTPS id 092CF1A009C
	for <internals@lists.php.net>; Mon, 20 May 2024 16:02:02 +0000 (UTC)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail;
	t=1716220976; bh=5okzED1pS9eRKIVfIVQN/nntR51f/SlB/8Lc98HhSsU=;
	h=In-Reply-To:References:Date:From:To:Subject:From;
	b=lm7ju5UZM7HZeo8GOkSkx85cvP529BId4AxfL8rGqJQafJG3X8//O3S/TXTcz+cwS
	 4ESb2t45+4xLMqAHZhaKz74MbSZDFctLgWyvqoW21FS8x/L5t/5d5YcLsBUKgngJLe
	 HyGCd6FWzmJKeaeYMiYS0g6MizbbWan3IdSBo/zDeg9EE2yiEFq1WO7Q1W7xKVCmEE
	 fHXxZqzmbID5Mz/5wzYWZIjtbdVqPgqvMeN70eYF0AKRZz4UH5bKdbdWmysqiaMj+P
	 10yCYj3FWa3r1I/bgqd8pgcf839405VclmhZrtwbU5DazYq4CAdkq2eJ5RVQL2CFQs
	 vQZYcHKj6Yzhw==
Received: from php-smtp4.php.net (localhost [127.0.0.1])
	by php-smtp4.php.net (Postfix) with ESMTP id 483DF18068A
	for <internals@lists.php.net>; Mon, 20 May 2024 16:02:56 +0000 (UTC)
X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) on php-smtp4.php.net
X-Spam-Level: 
X-Spam-Status: No, score=-0.1 required=5.0 tests=BAYES_50,DKIM_SIGNED,
	DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_MISSING,RCVD_IN_DNSWL_LOW,
	SPF_HELO_PASS,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=no
	autolearn_force=no version=4.0.0
X-Spam-Virus: Error (Cannot connect to unix socket
	'/var/run/clamav/clamd.ctl': connect: Connection refused)
X-Envelope-From: <larry@garfieldtech.com>
Received: from wfhigh2-smtp.messagingengine.com (wfhigh2-smtp.messagingengine.com [64.147.123.153])
	(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 <internals@lists.php.net>; Mon, 20 May 2024 16:02:55 +0000 (UTC)
Received: from compute1.internal (compute1.nyi.internal [10.202.2.41])
	by mailfhigh.west.internal (Postfix) with ESMTP id 678F3180007D
	for <internals@lists.php.net>; Mon, 20 May 2024 12:01:59 -0400 (EDT)
Received: from imap50 ([10.202.2.100])
  by compute1.internal (MEProxy); Mon, 20 May 2024 12:01:59 -0400
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
	garfieldtech.com; h=cc:content-type:content-type:date:date:from
	:from:in-reply-to:in-reply-to:message-id:mime-version:references
	:reply-to:subject:subject:to:to; s=fm1; t=1716220919; x=
	1716307319; bh=SrBTcipYX12z7USRKHiJvvkEQCNWNkXj6SlHOdw0Kz8=; b=s
	BK/yqYWgs5uDE1ol4ANUpFLGsLCzUw46rSdBI0X8Y+pribvU1yukStYho0zKTpBn
	vJA/2AgqhMfdbqxKVq7rGvvlBM7EtwUpuUPexemvnZD32sGl93C2NCrn/pShMxlb
	UOBJtDuGCB7OWxEiNUZEjsmUU6i/l86FtwujTBquybXNfRSvX6/wmAFhi5YQ0jJE
	p1ZXeT4USIdcPpsUnyvhxJijjfGDrXNtk7Tg32C3MrWg3fYe6zhmFdk753zcDP/H
	0CuowJIz3Dox3dlP+sgG1/XWKJegAX4IrgTrsbGE3xpHGQ2Glmv9WcMZfrTFMzUh
	Dm9CcA890XbWY4TeZ2cHw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=
	messagingengine.com; h=cc:content-type:content-type:date:date
	:feedback-id:feedback-id:from:from:in-reply-to:in-reply-to
	:message-id:mime-version:references:reply-to:subject:subject:to
	:to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=
	fm1; t=1716220919; x=1716307319; bh=SrBTcipYX12z7USRKHiJvvkEQCNW
	NkXj6SlHOdw0Kz8=; b=QsdcpYyusWbodBtnOTxA/i2Q55qGxrx2cmjhBI7AqRCA
	xyoLvnALxsUS1YdcIrnhoYEVn0YL2iMbvTg17w1nPdYc3+c5p9q2G0Pwy037fbC7
	trmo6Rja/e5mNxds2HrHF4CK4e+yDlan+rURB/NAXfh5w+RK7H6drUAPg6dAfNJ+
	Lxre93jVAQSUDqOVyJ4tlOKRoNtrZ3fusmS/c99dZcdi6lnJ6tNo4XioUVlZzl0b
	DSFvgV2RCt4RMr1PxvuBY7J9MhPRlZ9HFmsWWKhoy1lEUbDf4FenSv0pbpFy3Gpf
	4O2U3W0uHUluLIE3Iags8LneIBST8ePRPizE1Hd4qQ==
X-ME-Sender: <xms:9nNLZqMIxprumzAE8sX8ToNEzEzZ_a8bff4l6tXVhi6_zCENneroGg>
    <xme:9nNLZo87TmqNau8WtHFl55tcuePCUtSRcV7WGRDXdAR5kfcaZS3KjXWo5V5JsT03Z
    Tl5WpZBuNk6rA>
X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdeitddgjedtucetufdoteggodetrfdotf
    fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen
    uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne
    cujfgurhepofgfggfkjghffffhvffutgesthdtredtreertdenucfhrhhomhepfdfnrghr
    rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh
    hmqeenucggtffrrghtthgvrhhnpeeglefgkeduiedvvdetffeujefftdfhjeeiveehgfff
    keduveektddvledvvdfffeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh
    grihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh
X-ME-Proxy: <xmx:9nNLZhQuBm6ApCbT13Bnd2QW00RV0FprMXp2xiXKZgsltLXt2Mt5_w>
    <xmx:9nNLZqsCW31GK5mgFN-IIRCOWG0JXWjtCmn645a4YOXfUgQV11dzow>
    <xmx:9nNLZieJDSC-Q4HF1WEFPRIVnrDb-EEGWQWkxnig3XsQNiIjJqL71Q>
    <xmx:9nNLZu0L15G6NnlJc9WMUtJCJLYU-ywU4JnxlXuX0nG-k4bwCAR4xA>
    <xmx:93NLZkqxgict84YqHBYlBPopp9EZEgrshu1FS2uaIgnPR5j2msfLXH-0>
Feedback-ID: i8414410d:Fastmail
Received: by mailuser.nyi.internal (Postfix, from userid 501)
	id A810A1700096; Mon, 20 May 2024 12:01:58 -0400 (EDT)
X-Mailer: MessagingEngine.com Webmail Interface
User-Agent: Cyrus-JMAP/3.11.0-alpha0-480-g515a2f54a-fm-20240515.001-g515a2f54
Precedence: bulk
list-help: <mailto:internals+help@lists.php.net
list-unsubscribe: <mailto:internals+unsubscribe@lists.php.net>
list-post: <mailto:internals@lists.php.net>
List-Id: internals.lists.php.net
MIME-Version: 1.0
Message-ID: <133158d0-1371-4b7c-a2f4-242bfe99ce10@app.fastmail.com>
In-Reply-To: <47E8FDF4-9805-4A0B-A2E1-55CF8721253E@rwec.co.uk>
References: 
 <CAAX=eQNH0xyoRkMDThvG_aNS5Hub3tFD52v4PY3OZKT_zWaMmg@mail.gmail.com>
 <CAPzBOBN1M3H-ueqUtzfb_HPv2jZeDaYVTvXideVnx9QYG6LKeA@mail.gmail.com>
 <CAAX=eQPiRs0sq5z2xdtfV9bnf0waV6O+QaAUEfcM90Pwf3+M=g@mail.gmail.com>
 <878c09ca-860e-4c0c-85ae-2cd0246cda3c@rwec.co.uk>
 <5014b401-6341-44c6-a16e-f453ab52220c@app.fastmail.com>
 <47E8FDF4-9805-4A0B-A2E1-55CF8721253E@rwec.co.uk>
Date: Mon, 20 May 2024 16:01:38 +0000
To: "php internals" <internals@lists.php.net>
Subject: Re: [PHP-DEV] [DISCUSSION] Checking uninitialized class properties
Content-Type: text/plain
From: larry@garfieldtech.com ("Larry Garfield")

On Sat, May 18, 2024, at 5:41 PM, Rowan Tommins [IMSoP] wrote:
> On 18 May 2024 17:13:49 BST, Larry Garfield <larry@garfieldtech.com> wrote:
>>However, that breaks down with readonly properties, which are not allowed to have a sentinel.  Uninitialized is their sentinel, for better or worse.
>
> Sorry, I don't understand this statement at all. A readonly property 
> can be set to PatchState::KeepCurrentValue just like any other. If the 
> intention is that that state will be overwritten with an actual value 
> later, then it's not a readonly property. 
>
> I guess you have some different scenario in mind?
>
>
>> And as I noted earlier in the thread, when writing a serializer or other dynamic systems (an ORM probably would have the same issue), you really need to be able to differentiate between null and uninitialized.  Even if you think the uninitialized value is a sign of an error, it's coming from code you don't control so you have to be able to handle it somehow.
>
> If a property is uninitialized, the object is in an invalid state, and 
> attempting to read that property gives an error. That's by design, and 
> as it should be.
>
> Are you saying that you want to be able to detect the error before it 
> happens? Why?

For context, remember I maintain a serializer library, so I have to support objects that may indeed be in an invalid state, and depending on the incoming data may not be able to guarantee an object is in a valid state.  I have to do everything via reflection and/or visibility-busting closures.  I also maintain an attributes library that, necessarily, has multiple methods that get called post-constructor before the object is "ready."  Admittedly neither of these are common cases, but neither are they invalid cases.

Readonly's current design, and the (IMO, very bad) support from SA tools, works on the assumption that your readonly properties are 1. Based on constructor params; 2. are always guaranteed set after the constructor.  While those are true in the majority case, they're not true in the universal case.

IOW, "this readonly property is not set by the time the constructor is done, so your object is invalid, so your argument is invalid" is not a fair or accurate statement.  And even then, lots of code needs to be able to inspect an object to determine if it is valid or not, even if just to give the user a better error message than "Oops, you tried to read an uninitialized property, we gonna crash now."  (As noted, I maintain multiple such libraries.  ORMs would be the other big use case, I think.)

All of which is to say that, yes, there are use cases for an "is this property initialized" check that is less fugly than the get_object_vars() hack I have to rely on now.  

--Larry Garfield