Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:93678 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 61701 invoked from network); 1 Jun 2016 14:38:55 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 1 Jun 2016 14:38:55 -0000 Authentication-Results: pb1.pair.com header.from=guilhermeblanco@gmail.com; sender-id=pass Authentication-Results: pb1.pair.com smtp.mail=guilhermeblanco@gmail.com; spf=pass; sender-id=pass Received-SPF: pass (pb1.pair.com: domain gmail.com designates 209.85.214.41 as permitted sender) X-PHP-List-Original-Sender: guilhermeblanco@gmail.com X-Host-Fingerprint: 209.85.214.41 mail-it0-f41.google.com Received: from [209.85.214.41] ([209.85.214.41:35814] helo=mail-it0-f41.google.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id A6/A6-11325-E73FE475 for ; Wed, 01 Jun 2016 10:38:55 -0400 Received: by mail-it0-f41.google.com with SMTP id z189so81136420itg.0 for ; Wed, 01 Jun 2016 07:38:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=A4qKFbxWBwK8J0JVxyxsQO4H1i9pJJ2Mf9PnmsMrzDM=; b=rwd4nt2MwlehH9BCJ6VdYJOZJthOnfzIHpgd9GSBdk4jCvN+u03Fs5960gJaBR//EI AkiOItLjl83P5AE8zzFCrygdIkWj4AcqmHE+CRK2/X7nI/HMXKIpW4V1GIb5ewRIKVQc OgvlKnYJwUYXj/lIwRqq0x7E4taP4VQWRyEhCHUoAocz5AdWElQkEwFCrjXt91IApVT/ JKD1kfEwlNDKhQb5wFLZkL+3390I+w0dIlp0JX00B9GNJE64oGbBjW3ucAGhc07EnsCn SA4AHIvUKRdWVPfsmgbDH62MJylUSr884PjGz1fmK08e5aItGa9LfmjulEj0IJdXCxUq MmRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=A4qKFbxWBwK8J0JVxyxsQO4H1i9pJJ2Mf9PnmsMrzDM=; b=CsQ5ArRsqYTUGr1whr5+qY1mseBhPf3ALMjL4cvdEGywtPoKAcrV5NKsyXAqfOdw4O GINA1hVTfSw5AGR++TTE5CwBJzXPXwzWvybyJ78KuQGDw7oOs0bHB4OMu3KajIl9HQgT /Svzp7SeXqmlGaSub02OR2qM49Y6bxh2h0hMKzp/XwV4X7195mFf5vkys17rWcKZnQd9 8yN/VTteRZqjKDGqKerNfzhW0kAmHitWJKtnnpe+qiXReLMw2+ssalQraOBMXbQk/XrV a/MrxvRZZBxoqhxDNSuipIO6KE+TEcXKR+AJtBqETtYfdX4TeQ8ObA07ZnGKbXETqFme NhOw== X-Gm-Message-State: ALyK8tLPJo3EOqFoC1YMBolu1iIF758sMi4jwNeQ1MLd254mdVJTAqMUiWBKAm0ukyoZdhnxaxl7iNHQnDvrdQ== X-Received: by 10.36.103.4 with SMTP id u4mr6430286itc.45.1464791931602; Wed, 01 Jun 2016 07:38:51 -0700 (PDT) MIME-Version: 1.0 Received: by 10.50.228.163 with HTTP; Wed, 1 Jun 2016 07:38:32 -0700 (PDT) In-Reply-To: References: Date: Wed, 1 Jun 2016 10:38:32 -0400 Message-ID: To: Peter Cowburn Cc: Jesse Schalken , PHP internals Content-Type: multipart/alternative; boundary=001a114ac8f8c0ce6a053438726f Subject: Re: [PHP-DEV] Set object properties inline From: guilhermeblanco@gmail.com ("guilhermeblanco@gmail.com") --001a114ac8f8c0ce6a053438726f Content-Type: text/plain; charset=UTF-8 Hi, I very much liked the proposal, specially if we do consider a potential reusability if anyone ever decide to revisit Attributes RFC. It's out of scope how I'd see this implemented, so let me focus on the proposal only. There're some edge cases that need to be discussed and considered here. Here's one quick example: declare("foo", "bar"); class Foo { public $bar; } $f = new Foo() { foo = "bar" }; Should "foo" be considered as a property identifier or as a constant, which would then be converted into "bar" and then used as $f->bar = "bar"? Regards, On Wed, Jun 1, 2016 at 5:49 AM, Peter Cowburn wrote: > On 1 June 2016 at 03:15, Jesse Schalken wrote: > > > Hi internals, > > > > I often have code dealing with plain old PHP objects with properties and > no > > methods, either as a substitute for keyword arguments, or to represent a > > JSON or YAML document for a web service, configuration file or schemaless > > database. > > > > At the moment, instantiating an object and setting public properties > > requires a temporary variable for each object in the structure: > > > > $obj1 = new Obj1(); > > $obj1->prop1 = ...; > > $obj1->prop2 = ...; > > > > $params = new FooParams(); > > $params->prop1 = ..; > > $params->prop2 = ...; > > $params->prop3 = $obj1; > > > > $this->fooMethod($arg1, $arg2, $params); > > > > > > For large structures, this gets verbose very quick. There is a good > example > > of this here > > < > > > https://github.com/jesseschalken/fail-whale/blob/72870b37c4c21d19f17324a966344ec476b432a7/src/FailWhale/Introspection.php#L22 > > > > > involving > > 18 unnecessarily variables. > > > > I can remove the local variables by defining setters for all the > > properties: > > > > $this->fooMethod( > > > > $arg1, > > $arg2, > > (new FooParams()) > > > > ->setProp1(...) > > > > ->setProp2(...) > > > > ->setProp3((new Obj1()) > > > > ->setProp1(...) > > > > ->setProp2(...)) > > > > ); > > > > > > But now for each property I have to spend an extra 3-5 lines of code > > defining a setter, which is more code than it saved (unless the class is > > used heavily enough). > > > > I could define __construct() taking every property as a parameter, but > then > > each property has to be mentioned another three times (four times with a > > doc comment), and the type twice: > > > > class FooParams { > > > > public int $prop1; > > // ... > > > > > > public function __construct( > > int $prop1 > > // ... > > ) { > > > > $this->prop1 = $prop1; > > // ... > > > > } > > > > } > > > > > > and where the object is constructed, it isn't immediately visible what > the > > meaning of each positional parameter is without some IDE assistance (eg > > Ctrl+P in PhpStorm), and only specifying some parameters requires filling > > preceding ones with defaults. > > > > I could also define the __call() method to automatically expose setters, > > but then IDEs and static analysis can't understand what's going on (it > > can't see that those methods exist, what their parameters are and what > they > > return). @method doc comments on the class help, but that's another line > > for every property which I have to manually keep in sync with the real > > properties. > > > > It would be great if there was a simple shorthand syntax for setting > > properties on an object in-line, without needing to extract a variable: > > > > $this->fooMethod( > > $arg1, > > $arg2, > > new FooParams() { > > prop1 = ..., > > prop2 = ..., > > prop3 = new Obj1() { > > prop1 = ..., > > prop2 = ..., > > }, > > } > > ); > > > > While it's not as concise as your example, anonymous classes can do this > already after a fashion. > > $this->fooMethod( > $arg1, > $arg2, > new class() extends FooParams { > // Constructor because prop3's value isn't a constant expression > function __construct() { > $this->prop1 = '...'; > $this->prop2 = '...'; > $this->prop3 = new class() extends Obj1 { > public $prop1 = '...'; > public $prop2 = '...'; > }; > } > } > ); > > > > > > > > This way the structure can be written directly in the code as an > expression > > and FooParams and Obj1 remain simple containers for properties. > > > > The grammar might look like (I haven't used bison/yacc before): > > > > expr_without_variable: > > /* ... */ > > | expr '{' inline_set_properties '}' > > ; > > > > inline_set_properties: > > /* empty */ > > | identifier '=' expr > > | identifier '=' expr ',' inline_set_properties > > ; > > > > > > (Although I think that would conflict with the alternative $var{8} syntax > > for array/string offset.) > > > > Has this been explored before? What problems can you foresee (or have > been > > foreseen) with such a feature? > > > > Thanks > > > -- Guilherme Blanco Lead Architect at E-Block --001a114ac8f8c0ce6a053438726f--