On Thu, Jun 2, 2016 at 12:38 AM, guilhermebla...@gmail.com <
guilhermebla...@gmail.com> wrote:

> 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"?
>

My intention was for "expr->prop = ..." to be equivalent to "expr { prop =
... }", except obviously the result is the object itself and multiple
properties can be assigned. So the property name is written directly as an
identifier, and wouldn't be looked up as a constant. If expression property
names are required I suppose it should mirror the "expr->{expr} = ...;"
syntax and become "expr { {expr} ... }".

Turns out there is already a "property_name" production
in zend_language_parser.y (and also "member_name", but I'm not sure what
the difference is), so the grammar would become:

expr_without_variable:
        /* ... */
    |   expr '{' inline_set_properties '}'
;

inline_set_properties:
        /* empty */
    |   property_name '=' expr
    |   property_name '=' expr ',' inline_set_properties
;




>
> Regards,
>
>
> On Wed, Jun 1, 2016 at 5:49 AM, Peter Cowburn <petercowb...@gmail.com>
> wrote:
>
>> On 1 June 2016 at 03:15, Jesse Schalken <m...@jesseschalken.com> 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
>

Reply via email to