Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:56705 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 32316 invoked from network); 1 Dec 2011 18:28:33 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Dec 2011 18:28:33 -0000 Authentication-Results: pb1.pair.com smtp.mail=ircmaxell@gmail.com; spf=pass; sender-id=pass Authentication-Results: pb1.pair.com header.from=ircmaxell@gmail.com; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.216.49 as permitted sender) X-PHP-List-Original-Sender: ircmaxell@gmail.com X-Host-Fingerprint: 209.85.216.49 mail-qw0-f49.google.com Received: from [209.85.216.49] ([209.85.216.49:56579] helo=mail-qw0-f49.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 95/09-10027-057C7DE4 for ; Thu, 01 Dec 2011 13:28:33 -0500 Received: by qabj40 with SMTP id j40so1770892qab.8 for ; Thu, 01 Dec 2011 10:28:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type:content-transfer-encoding; bh=8Hv+RX6XxIp3fwqmdlbC7+s+e20XsIFrVI4y0I1B8bU=; b=uHtU6npqF1Bhp5htNmMu9n6sFXKZfYhFL5XvXV/hIqDTw4RuX6dwgzpCUNMoEPkfSH q2vUXJNUztmUF+Rk5bektRgEslCed9H2XHMx+P30mwLgpzYin6Fds6Xg9Sl9K0WSwEO5 Kj+A7MiWCrd/Y3FKWyHg713xU3NgoYZ9GSszc= MIME-Version: 1.0 Received: by 10.229.63.221 with SMTP id c29mr1084259qci.266.1322764110008; Thu, 01 Dec 2011 10:28:30 -0800 (PST) Received: by 10.229.225.201 with HTTP; Thu, 1 Dec 2011 10:28:29 -0800 (PST) In-Reply-To: <4ED7BAC2.20805@ralphschindler.com> References: <4ED6713D.2050009@ralphschindler.com> <4ED67DCB.5090102@ralphschindler.com> <4ED68940.3050502@ralphschindler.com> <90D867E2-E6FB-481D-B57C-911E5FE6A418@gmail.com> <4ED7BAC2.20805@ralphschindler.com> Date: Thu, 1 Dec 2011 13:28:29 -0500 Message-ID: To: Ralph Schindler Cc: Will Fitch , Nikita Popov , internals Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Subject: Re: [PHP-DEV] 5.4's New De-referencing plus assignment From: ircmaxell@gmail.com (Anthony Ferrara) To be honest, I'm not a fan of the proposal as written since it can't accept arbitrary expressions inside the parenthesis. Now, if you could do any expression inside, then I would +1 for completeness. But since that's not really possible with the current parser (or language specification), I'm not sure... Read my comments inline On Thu, Dec 1, 2011 at 12:34 PM, Ralph Schindler wrote: > I'll respond to all at once ;) > > > > On 11/30/11 1:58 PM, Will Fitch wrote: >> >> If that's the case, then why not just add whatever $options is as a >> parameter to your constructor. =A0I'm not totally against this concept, >> but this use is moot. > > > > I'm simply trying to find usefulness in the new feature of > > =A0 =A0$x =3D (new Foo)->bar(); > > That's not useful to me. =A0Mainly b/c if you don't get a handle on the > object, what was the point in the first place? An example that was given before is to check to see if a class (string) implements an interface: if ((new ReflectionClass($class))->implementsInterface($interface)) {} Where you don't *need* the object afterwards, all you need is to call a single method on it... > PHP already has a place for this in functions, static methods, AND if you= 're > idea of OO programming is wrapping stateless functions in classes for > "grouping" - in namespaces. Well, perhaps. However not all use-cases for this are stateless. The reflection example is one where you need to initialize a state prior to calling that method. Additionally, this lends itself perfectly to one particular OOP design pattern: Value objects. It would let you do: $value =3D (new Value(1))->addTo(new Value(2)). Since each value object is completely immutable, there's no reason to persist it longer than you actually need it (unless you're using a flyweight design pattern as well, and caching objects to reduce instantiation overhead)... A good use-case for this is interacting with dates. $age =3D (new DateTime($birthday))->diff(new DateTime())->format('%R%a days= '); Right now, the docs have it as separate lines, even though each object is only used exactly once... >> The plain (new Foo)->bar() syntax*is* =A0useful for cases like (new >> >> ReflectionClass($class))->implementsInterface('Foo'), where you need >> only one single bit of information from a class. > > Sure that is useful.. Although that looks more to me like an edge case th= an > my idea of how expression-dereferencing would work. =A0Like I said above,= if > your object doesn't do much more than what a function would do, why not j= ust > file a feature request for Reflection to have a factory method on every > class? I would argue that adding a factory method for this purpose is actually *less* readable and worse. The rationale is simple. If you don't know how the method works internally, can you tell me what is happening here (just form method names): ReflectionMethod::factory($class, $method)->setAccessable(true); ReflectionMethod::factory($class, $method)->invoke($obj); Wherease with the explicit inline new, it's absoltuely clear both are happening on distinct objects: (new ReflectionMethod($class, $method))->setAccessable(true); // pointless, I know (new ReflectionMethod($class, $method))->invoke($obj); > Do we really want to encourage people to create objects for the purpose o= f > calling a single method and tossing away the original object? You'd be > better off using a function or a static method if that is what you want. > =A0Furthermore, if you want to chain methods, that is also dangerous sinc= e PHP > cannot do type enforcement on return values. =A0So, Honestly, yes I would encourage that. If you're *really* never going to use the object again after that one call, why add an entry to store it in a variable when you could just throw it away as soon as you're done (saving a GC cycle)... Now, you could argue (as I think you did) that most times people do that they shouldn't be using a class, but a function (I consider static methods all but identical to a function). And that's a fair point to make. But it doesn't mean that there aren't valid use cases. Heck, PHP implemented goto... > =A0$instanceOfFooOrCoolResult =3D (new $foo)->do()->something()->cool(); > > needs to somehow guarantee that all methods of the type $foo will return > $this. =A0(BTW, this is not an argument for my feature as much as its an > argument as much as its one for "if we're going to do something, why not = do > it correctly in the first place".) =A0The correct path here, IMO, would b= e to > simply carry the expression result (since we're using '(' expr ')' out an= d > allow dereferencing on whatever comes out of it. > I would argue though that your syntax is completely possible today: $foo =3D new Foo; $foo->bar(); What's the reason to put that in a single line? Aside from terseness, is there any other benefit? With the new dereference, one benefit is that no variable is populated when none is needed. But in your case, you need both variables... > > Here is a more contextual use case for my argument though: > > =A0$rows =3D ($sql =3D new Sql)->from($table)->execute(); > =A0// i can interact with both $sql and $rows at this point. Honestly, I find that very hard to read. At a glance, I don't know what's going on. Even looking closer at it, it takes a few seconds to comprehend what's happening. > > -ralph