Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126612 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 B179A1A00BC for ; Thu, 6 Mar 2025 22:31:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1741300144; bh=qx/aMG6QxEkGRFgNC5K+My0baIKLXW4OPqreFYLdO34=; h=Date:Subject:To:References:From:In-Reply-To:From; b=gSaUudV52K20bTt11vvHsLdgbB72avrRi/UlMcYnjH9z64K9Kl1tR/dMYGC+u3XPD to3IKfLvtGUIbMkuZ2autSGaF8y+T3g/w9eaCLWB8cAhlPBDlTWCgv0hCNUpKZ/+E3 wyMquhryJq3w9401RSRXf5867xZFgyKG/obrx2a8zvL07jqHM0ZEYDwAK/iPqp0dui xlr0BetPo+Nl417BsRsO8gXYIMqPIOVLkw2KUIb1jtnHD2IbhPZrZnCWS0ninh7K+n 4LJYGzcnEnDe+dSt41Z37k6ooswVEvmLm1hze6+mMAxHoZut5v3hCunipTcgGEx4Zo 1FPbx7YtIPh6g== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id BA69E180081 for ; Thu, 6 Mar 2025 22:29:03 +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=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,SPF_HELO_NONE, SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from chrono.xqk7.com (chrono.xqk7.com [176.9.45.72]) (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 ; Thu, 6 Mar 2025 22:29:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bastelstu.be; s=mail20171119; t=1741300297; bh=irBCd8fPNYczDXv10ZlZkx5Gsjq7m3yhv4wKAsCSJkw=; h=Message-ID:Date:MIME-Version:Subject:To:References:From: In-Reply-To:Content-Type:from:to:cc:subject:message-id; b=mH21cAn4268RdP1poQKP4lsJVi5rUKW4OrmWKuQjXPZXTVBW9A0JLNNQY7Q32M5N9 FdWcvITDnJQfcDn8N9EE/rg8YgXw7YxPMUgpAmvYdlifdtY0X4fPz8DqgEkJ+haGbw L24Del2rtotgCqJuMmlefH00mpxJKRrigD/38sbFMBDoZyTaK7uVymJFZUGmqedMqc rdkBfKlUq998AGKF5LZg+B39++TPMVOej3WdAiZfVrXMW2nsyDEJPrKJm9D+M+7fg9 os2oYGtT97aH/z2DYuBpZo4bxJkP+TlfvYjdZvt0nBpXqkV6S36SHeDcHzZgazrSoz wxN/xkrl9gSOg== Message-ID: Date: Thu, 6 Mar 2025 23:31:35 +0100 Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Subject: Re: [PHP-DEV] RFC: short and inner classes To: Rob Landers , Niels Dossche , internals@lists.php.net References: <8303823b-a193-411f-bb60-c0221e7f29dc@bastelstu.be> Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit From: tim@bastelstu.be (=?UTF-8?Q?Tim_D=C3=BCsterhus?=) Hi On 3/6/25 23:05, Rob Landers wrote: >> >> Closure::fromCallable('Outer::Inner::method'); > > You end up with: > > object(Closure)#1 (1) { > ["function"]=> > string(20) "Outer::Inner::method" > } Okay, does calling the closure work and correctly call the `method` on the inner class? The question was intended to make sure that the implementation for callables uses the correct `::` to split. Here's another one that might be interesting: Closure::fromCallable(["Outer::Inner", "method"]); Closure::fromCallable(["Outer", "Inner::method"]); >> constant('Outer::Inner'); > > This returns: > > string(12) "Outer::Inner" Okay, so this behaves as a constant containing the class name. I assume it's with the full namespace if the outer class is namespaced? I'm not sure if I want this to work like this (i.e. whether this should be an error). >> $inner = 'Inner'; >> Outer::{$inner}; > > This does nothing (but resolves to "Outer::Inner") It's consistent with `constant()` and that's good. >> … and any other meta-programming functionality working on class >> constants or static methods. >> >> Also, what will happen for: >> >> class P { >> class Inner { } >> } >> >> class C extends P { >> const Inner = 'x'; >> } >> >> (and vice versa) > > This is a really good one. If for no other reason than I did a really poor job of explaining resolution(?) in the RFC. `P::Inner` belongs to `P`, not to `C`, so you can do `new C::Inner()` and it will resolve to `P::Inner()`: I don't think the RFC explains “resolution” at all. That's why I'm asking with those specific “edge-casey” examples, so that the RFC explicitly spells out the behavior. This is not something that should be “implementation defined”, but something where an explicit design decision has been made. I also don't understand why `new C::Inner()` (w|sh)ould resolve to `P::Inner()`. I think my expectation of the code snippet above would be that it is an error. Likewise, LSP being ignored for inner classes raises an interesting question about the behavior of: class P { class Inner { public function __construct(public string $foo) { } } public static function create() { return new static::Inner('x'); } } class C extends P { class Inner { public function __construct(public int $bar) { } } } What happens if I call `C::create()`? This should also be specified in the RFC (and tested with a .phpt test). > As with other static things in PHP, you can do some really strange things like this. This is similar to how you can redefine static constants in subclasses. We should remove the number of strange things, not add to them. Best regards Tim Düsterhus