Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:103368 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 85807 invoked from network); 22 Oct 2018 17:23:24 -0000 Received: from unknown (HELO out3-smtp.messagingengine.com) (66.111.4.27) by pb1.pair.com with SMTP; 22 Oct 2018 17:23:24 -0000 Received: from compute7.internal (compute7.nyi.internal [10.202.2.47]) by mailout.nyi.internal (Postfix) with ESMTP id 9C42E2208B for ; Mon, 22 Oct 2018 09:38:02 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 22 Oct 2018 09:38:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=jJQUKp T2OwkH6CFXyXsRjQe0pu6TLfySgLi+Ns97Cn0=; b=yRuumwQ5qfUlfuUTA9ElID bAmWIsTuGtw8/gJa10Q1G2ThpxMroEOXhxNY+VlApJsz0Ujwdy/8y4WzHmGsJjbg dEF1FVutP0i4FUjDn6fEL2/OXedb7qQx1bZTgwwS5Ij/kA+HXUDdaSxm7pQptBjo GLpQInTzGf+WpFYOyC1B7az9TipcTP+7G8EVbGcYVf2pZbntRh3tHwOCptSwU52Z 2e6EzomCUqXZL26tJGJs5R4vWiAl60QmhrULQilgXcdAYtx2P55jkugz+QmDzHEk KJ+Pqam7HJ+plxoxFRwQpRuD7kb/HMIra6RazATc6YUip8Hk2CdzJo/NUD8TSRpw == X-ME-Sender: X-ME-Proxy: Received: from vulcan.localnet (216-80-30-152.s3222.c3-0.frg-cbr1.chi-frg.il.cable.rcncustomer.com [216.80.30.152]) by mail.messagingengine.com (Postfix) with ESMTPA id 0E48F102A0 for ; Mon, 22 Oct 2018 09:38:02 -0400 (EDT) To: internals@lists.php.net Date: Mon, 22 Oct 2018 08:38:01 -0500 Message-ID: <1914897.W2W4DmmTqA@vulcan> In-Reply-To: <0047f3c7-3e9e-ef6f-2d7a-e58c316ea751@gmail.com> References: <0047f3c7-3e9e-ef6f-2d7a-e58c316ea751@gmail.com> MIME-Version: 1.0 Content-Type: multipart/signed; boundary="nextPart3288100.FFtkqNfUZP"; micalg="pgp-sha512"; protocol="application/pgp-signature" Subject: Re: [PHP-DEV] Composition over inheritance: native support for "delegating" methods? From: larry@garfieldtech.com (Larry Garfield) --nextPart3288100.FFtkqNfUZP Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" On Sunday, October 21, 2018 12:41:04 PM CDT Rowan Collins wrote: > Hi, > > I've been thinking about how the language could better support > Composition patterns like Decorators and Proxies, using some simple > syntax sugar not dissimilar to Traits. > > > Example problem: > > The other day, I was writing a session handler which slightly modified > the behaviour of one provided by a library. The library implementation > was closed for inheritance (a final class accessed via a factory which > handled configuration), so I wrote a Decorator class, which added a > single method. Everything worked fine, using Composition over > Inheritance. But... > > In order for my Decorator class to implement the > SessionHandlerInterface, I needed to write six stub functions, each of > the form "function foo($bar) { return > $this->delegatedHandler->foo($bar); }". With whitespace and docblocks, > these amount to nearly 90 lines of code, as much as the actual custom > code in the Decorator. > > > Possible solution: > > Methods in a Decorator or Proxy which are delegated without any > additional functionality can easily be generated programmatically, so > could the language provide syntactic sugar to do this for you? > > - To delegate to an instance held in a property, add the "delegate" > keyword at the end of the property declaration, followed by a list of > method names to generate, e.g. "private Foo $foo delegate { doX, doY };" > - Delegating static method calls to another class could also be > supported, using a standalone declaration like "static delegate > ClassName { staticMethodName };" > - As with Traits, the generated methods would be stitched into the class > at compile time, and not distinguishable in reflection. > - Delegated methods could be used to implement an interface, either > completely or partially (again, like Traits). > - Other features of traits could be included if they were seen as > useful, such as aliasing ("delegate { foo as bar }") and changing > visibility ("delegate { foo as private }") > > > Example: > > class SpecialSessionHandlerDecorator implements > \SessionHandlerInterface, SpecialInterface { > private \SessionHandlerInterface $delegatedHandler delegate { > close, destroy, gc, open, read, write > }; > > public function specialMethod() { ... } > } > > > What do people think? Would this be useful, or am I missing some major > limitation or implementation problem? Does any other language provide a > feature like this which we can learn from? > > Regards, I like this in concept. However, my big issue is return values. Sometimes when proxying to an object like that, you want to return the return value of the proxied method. Sometimes when proxying to an object like that, you're supposed to return $this, but your $this is different than the proxied object's $this. Detecting when the generated proxy method should pass through the return value from the method it's proxying for vs when it should override it somehow sounds non-simple. --Larry Garfield --nextPart3288100.FFtkqNfUZP Content-Type: application/pgp-signature; name="signature.asc" Content-Description: This is a digitally signed message part. Content-Transfer-Encoding: 7Bit -----BEGIN PGP SIGNATURE----- iQEzBAABCgAdFiEE/ph/GXfY8v0YwFBp4MMKwDFxYXcFAlvN0rkACgkQ4MMKwDFx YXeZHggA0iGhjGMD21kKcso4WmgpJYH4xMZPxz12GV2Q0aLHL8rauROrPFbssPEg HO3ixao52VRHc0zRZ651kvG8IleDGhQErzEOqU3DGhf0mfwll67hRx+bIwgk7Q3H pNYVIv0PabOdBsBpiDe2JMgne6VP2kKn5nudVcpcSmt5OR1MG2DWagmnYAVitGLe kNKVbgiJd06uVEAP7R6gW5JsFMeWjWfV0wfVvUxNa9ewatz2AxK1u2PqRKjoDSxU 7q8CaTyzP/6JGlFPvYIW0h+4Dhtn3CndXUGTEwwrXsqcSXP7RGhRdM/etSSgTHH+ EfCI23trwDmCAQxPTwVrmnpSepmQow== =mdCg -----END PGP SIGNATURE----- --nextPart3288100.FFtkqNfUZP--