Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:123519 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 118981A009C for ; Wed, 5 Jun 2024 15:31:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1717601563; bh=ABOwjhzeT49hA2Y9aI8L9EuGfNm3oiP6hniZ04bGsa4=; h=In-Reply-To:References:Date:From:To:Subject:From; b=KvQjYF9p2vjiiyeyovuo9mIY4lI1Z64DNMiMQ+V35qX99aC2L0NPJmCE5aM5pNO0d PARzcGjdi+AKZHFeIqjre5qcPGL256z693IwlEkBw3w9XuLpXdEsb5F/fSiHRyL7Fo VFZkLe1KHtiwGG4dVujvPy/Q+5TEPz173ihvu7JdC9hqE/IAepeF2eG8vp/Q+cD5lb 241BYDZJB0UXwCuhLzBWDGoiJq+jFBvtnJkKviNBkwyAg7FBgKyAMOU0VSg3AFrfc5 ya34LadufCaJeIvLhTeQbWS0bDKwG5angsaYFcXNFRuxgOhE2k5Ja7YBqgQ+RQNfC1 3soyp6rw0v/Bg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 10065180A4B for ; Wed, 5 Jun 2024 15:32:42 +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: Received: from fout2-smtp.messagingengine.com (fout2-smtp.messagingengine.com [103.168.172.145]) (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 ; Wed, 5 Jun 2024 15:32:41 +0000 (UTC) Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailfout.nyi.internal (Postfix) with ESMTP id 4CB5813800E2 for ; Wed, 5 Jun 2024 11:31:36 -0400 (EDT) Received: from imap50 ([10.202.2.100]) by compute1.internal (MEProxy); Wed, 05 Jun 2024 11:31:36 -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=1717601496; x= 1717687896; bh=ckS2Ylw5nvyDveX0PBVnUWiYpfctby9EDAp81EILtOQ=; b=h EZ8qx9bfWCHWcMbPgdTYXq4UaBg3x8sXnDph5RPuy72AlhexYUr54WqXsJtrhmDC lCK7H/D4FjgYbkDgvNUKcHwL2nDi/OX9/A7FaaXWUSf0+nqx79ycMOPaYlX/Z/rk RP6ec6BZJe2kgRPr3FROB0pI2TzCDUPCnxG7GXAaDTA+kdXoMpyDAb1ykJ4tYZI9 mlPGoq7x/6iq6RzV8yCPiLDUnD21ILV9g25BjPJwq+cQwLSC2pQAnOQRj/jXomA5 5l7ky/FEG2IBYSMZ4LBjodbDdXm6xbMoXpVr6wmNqaX4IrIp9p84PwWGaa6Y4j+S Z0G0dQKqBaGIRJryqyT9A== 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=1717601496; x=1717687896; bh=ckS2Ylw5nvyDveX0PBVnUWiYpfct by9EDAp81EILtOQ=; b=YYCRHtDIYwJmg98/FYIXtWDdjC3Kyr2PXjF/GfE6wj8k 06drsUQTTHZMDmYkAy0mVK2yBCn2qq6AGy9AhZBhIAxwJ6a3yoIFkgyZp/hmYKkl k5+m7FVHilvXjFsBeFXKZ4RZNt6egzEArgMjqj5uPCInnr60K7Ntcpf/NbGD93qg mz73ioB7oQLmcrznJ3zPiZRY3uQmtwxsgiRdJ9aFGL+CZx1RUxJ/za0pAf02Oox9 bWZtdtw6WJSrc9AVZBburaj+6mA2IlF2Uty1KP4+7L0OBVa2WvgoQOQTPdp8kemz 8R0AYDT34Eecm3Bk9DMfM7IXBZtndU0KmzCTv72HYA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdeliedgkeelucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepofgfggfkjghffffhvffutgesthdtredtreertdenucfhrhhomhepfdfnrghr rhihucfirghrfhhivghlugdfuceolhgrrhhrhiesghgrrhhfihgvlhguthgvtghhrdgtoh hmqeenucggtffrrghtthgvrhhnpeeglefgkeduiedvvdetffeujefftdfhjeeiveehgfff keduveektddvledvvdfffeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpehlrghrrhihsehgrghrfhhivghlughtvggthhdrtghomh X-ME-Proxy: Feedback-ID: i8414410d:Fastmail Received: by mailuser.nyi.internal (Postfix, from userid 501) id E77D41700093; Wed, 5 Jun 2024 11:31:35 -0400 (EDT) X-Mailer: MessagingEngine.com Webmail Interface User-Agent: Cyrus-JMAP/3.11.0-alpha0-497-g97f96844c-fm-20240526.001-g97f96844 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net MIME-Version: 1.0 Message-ID: In-Reply-To: References: Date: Wed, 05 Jun 2024 15:31:15 +0000 To: "php internals" Subject: Re: [PHP-DEV] [RFC] Lazy Objects Content-Type: text/plain From: larry@garfieldtech.com ("Larry Garfield") On Wed, Jun 5, 2024, at 2:50 PM, Arnaud Le Blanc wrote: > Good point. The Mutex constructor is called during "new Mutex()", but > the object is made lazy after that, and the destructor is never > called. > > We have made the following changes to the RFC: > > - makeLazyGhost / makeLazyProxy will call the object destructor > - A new option flag is added, `ReflectionLazyObject::SKIP_DESTRUCTOR`, > that disables this behavior > > This is not ideal since the intended use of these methods is to call > them on objects created with newInstanceWithoutConstructor(), or > directly in a constructor, and both of these will need this flag, but > at least it's safe by default. > > Thanks again for the feedback. > > Best Regards, > Arnaud Let me make sure I am following, since I'm still having a hard time with the explanation in the RFC (as I discussed with Nicolas off list). The two use cases intended here are, essentially, "delay invoking the constructor until first use" (ghost) and "sneak a factory object in the way that is called on first use" (virtual). Right? The ghost initializer callback is basically an alternate constructor (which will probably just call the real constructor in the typical case), and the virtual initializer callback is basically the body of the factory object. So the most common ghost implementation for a service would be something like: $c = the_container(); $object = new ReflectionClass(Foo::class)->newInstanceWithoutConstructor(); $initializer = static function(Foo $foo) => $foo->__construct($c->dep1, $c->dep2, $c->dep3); $lazyReflector = ReflectionLazyObject::makeLazyGhost($object, $initializer, ReflectionLazyObject::SKIP_DESTRUCTOR); Am I following? Because if so, the proposed API is extremely clunky. For one thing, using an input/output parameter ($object) is a code smell 99% of the time. It's changing an un-constructed object into a ghost object, and returning... um, I'm not sure what. It also means I need to use both reflection classes in different ways to achieve the result. It seems a much cleaner API would be something like: $object = new ReflectionClass(Foo::class)->newInstanceWithLazyConstructor($initializer); In which case it becomes a lot more obvious that we are, essentially, "swapping out" the constructor for a lazy one. It also suggests that perhaps the function should be using $this, not $foo, as it's running within the context of the object (I presume? Can it call private methods? I assume so since it can set private properties.) That would also suggest this API for the other approach: $initializer = static function() => new Foo($c->dep1, $c->dep2, $c->dep3); $object = new ReflectionClass(Foo::class)->newInstanceWithLazyFactory($initializer); In which case $object is the proxy, and gets "swapped out" for the return value of the $initializer on first use. Am I understanding all this correctly? Because if so, I think the above simplified API would make it much more obvious what is going on, much easier to work with, easier to document/explain, and simple enough that it could conceivably be used in cases outside of DI or ORMs, too. If I'm way off and don't understand what you're doing, then please explain as I'm clearly very confused. :-) --Larry Garfield