Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Lester Caine
On 01/06/16 22:09, Rasmus Schultz wrote:
> This tendency to "defend" the dynamic side of the language, as though
> static features were somehow an "attack" on dynamic features, befuddles me.
> 
> These two sides of the language do not compete with each other - they
> complement each other.

That is perhaps what *I* am looking for. Being able to manage the
attributes of a variable be it statically or dynamically defined should
be identical. My 'attack' is that all the current discussions are on
developing the static side without any mention of adding the same
constraint system to a list of dynamic properties.

-- 
Lester Caine - G8HFL
-
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Rasmus Schultz
> The drive to make everything as 'static' as possible misses
> the whole point that PHP is a DYNAMIC scripting system.

I think that line of argumentation is pretty outdated - it may have been
valid many years ago, but by now, PHP is not purely dynamic; far from it.
It's a gradually-typed language, and more so with scalar type-hints
recently added, and typed properties and nullable types coming up.

The drive to enhance the static side of the language doesn't miss a point,
nor does it take away from the dynamic side of the language - the whole
point of gradually-typed languages is the ability to choose between static
and dynamic in each situation.

This tendency to "defend" the dynamic side of the language, as though
static features were somehow an "attack" on dynamic features, befuddles me.

These two sides of the language do not compete with each other - they
complement each other.

Just interjecting a general remark here, I'm not commenting on the proposed
feature specifically.


On Wed, Jun 1, 2016 at 10:41 PM, Lester Caine  wrote:

> On 01/06/16 21:09, Jesse Schalken wrote:
> > On Wed, Jun 1, 2016 at 7:40 PM, Lester Caine  wrote:
> >
> >> Morphed into simply passing an array to the constructor ...
> >>
> >> $static1 = new Data\StaticVariable( array(
> >>   'name' => 'variable name',
> >>   'value'=> $unknown1,
> >>   'functionName' => 'blahFunction' ) );
> >>
> >> // className defaults to null
> >>
> >> Of cause the short cut at that time was to drop the names and simply
> >> count the variables, but what this replaces is all the complications of
> >> named parameters and allowed passing objects in such as '$unknown1'
> >
> > This works fine to remove the temporary variable but compromises two
> things
> > that I think are very important:
>
> Which was the start of the discussion when 'arrays' were being pushed as
> a 'solution' back in the PHP5.1/2 timescale.
>
> >1. IDE tooling and static analysis. An IDE can't autocomplete property
> >names as array keys, because it doesn't know the array keys are
> properties,
> >nor can it ensure that the properties actually exist, are visible,
> and are
> >being assigned the correct type. If I do a "Find Usages" on a
> property, it
> >may appear to be only read and never set, implying I can remove the
> >property and replace all the reads with the default value. Any static
> >analysis tool would have the same trouble.
>
> Hard coding the list of names just so you can add 'static analysis' is
> only one style of working. My set of array keys come from the database
> schema, which is another way of defining and typing your parameter set.
>
> >2. Performance. The code spends time building a temporary hash table
> >just to loop over it, look up each key in the object's property table,
> >check visibility, check type, assign it, and discard the hash table.
> That's
> >a lot of overhead just to assign some properties. With a dedicated
> inline
> >property assignment syntax, a normal bunch of "assign property"
> bytecode
> >instructions can be output and the PHP runtime will cache the property
> >offsets and assign them directly, and can elide the property type
> check if
> >the optimiser knows it will pass. HHVM can even burn the property
> offset
> >right into the compiled machine code. That's *way *faster. (At least
> >that's how I was told it works when I asked here a couple of weeks
> ago.)
>
> If your starting point is an array of database fields which are enhanced
> with the relevant type and constraint attributes, then 'performance'
> starts from that base. That was the base we were working on 15 years
> ago, and trying to replace that with hard coded 'PHP only' code does not
> remove that. The drive to make everything as 'static' as possible misses
> the whole point that PHP is a DYNAMIC scripting system.
>
> --
> Lester Caine - G8HFL
> -
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Lester Caine
On 01/06/16 21:09, Jesse Schalken wrote:
> On Wed, Jun 1, 2016 at 7:40 PM, Lester Caine  wrote:
> 
>> Morphed into simply passing an array to the constructor ...
>>
>> $static1 = new Data\StaticVariable( array(
>>   'name' => 'variable name',
>>   'value'=> $unknown1,
>>   'functionName' => 'blahFunction' ) );
>>
>> // className defaults to null
>>
>> Of cause the short cut at that time was to drop the names and simply
>> count the variables, but what this replaces is all the complications of
>> named parameters and allowed passing objects in such as '$unknown1'
> 
> This works fine to remove the temporary variable but compromises two things
> that I think are very important:

Which was the start of the discussion when 'arrays' were being pushed as
a 'solution' back in the PHP5.1/2 timescale.

>1. IDE tooling and static analysis. An IDE can't autocomplete property
>names as array keys, because it doesn't know the array keys are properties,
>nor can it ensure that the properties actually exist, are visible, and are
>being assigned the correct type. If I do a "Find Usages" on a property, it
>may appear to be only read and never set, implying I can remove the
>property and replace all the reads with the default value. Any static
>analysis tool would have the same trouble.

Hard coding the list of names just so you can add 'static analysis' is
only one style of working. My set of array keys come from the database
schema, which is another way of defining and typing your parameter set.

>2. Performance. The code spends time building a temporary hash table
>just to loop over it, look up each key in the object's property table,
>check visibility, check type, assign it, and discard the hash table. That's
>a lot of overhead just to assign some properties. With a dedicated inline
>property assignment syntax, a normal bunch of "assign property" bytecode
>instructions can be output and the PHP runtime will cache the property
>offsets and assign them directly, and can elide the property type check if
>the optimiser knows it will pass. HHVM can even burn the property offset
>right into the compiled machine code. That's *way *faster. (At least
>that's how I was told it works when I asked here a couple of weeks ago.)

If your starting point is an array of database fields which are enhanced
with the relevant type and constraint attributes, then 'performance'
starts from that base. That was the base we were working on 15 years
ago, and trying to replace that with hard coded 'PHP only' code does not
remove that. The drive to make everything as 'static' as possible misses
the whole point that PHP is a DYNAMIC scripting system.

-- 
Lester Caine - G8HFL
-
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php



Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Jesse Schalken
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 
> 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,
>>   

Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Jesse Schalken
On Wed, Jun 1, 2016 at 7:49 PM, Peter Cowburn 
wrote:

>
> 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 = '...';
> };
> }
> }
> );
>
>

While that does avoid the temporary variable it seems more verbose than the
temporary variable was to start with, even more so if you want to use
variables from the outer context, since you have to thread them through the
constructor.

It also seems excessive adding a whole new (anonymous) class to the runtime
just to avoid a temporary variable, but maybe that doesn't matter.


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Jesse Schalken
On Wed, Jun 1, 2016 at 7:40 PM, Lester Caine  wrote:

> Morphed into simply passing an array to the constructor ...
>
> $static1 = new Data\StaticVariable( array(
>   'name' => 'variable name',
>   'value'=> $unknown1,
>   'functionName' => 'blahFunction' ) );
>
> // className defaults to null
>
> Of cause the short cut at that time was to drop the names and simply
> count the variables, but what this replaces is all the complications of
> named parameters and allowed passing objects in such as '$unknown1'
>

This works fine to remove the temporary variable but compromises two things
that I think are very important:

   1. IDE tooling and static analysis. An IDE can't autocomplete property
   names as array keys, because it doesn't know the array keys are properties,
   nor can it ensure that the properties actually exist, are visible, and are
   being assigned the correct type. If I do a "Find Usages" on a property, it
   may appear to be only read and never set, implying I can remove the
   property and replace all the reads with the default value. Any static
   analysis tool would have the same trouble.
   2. Performance. The code spends time building a temporary hash table
   just to loop over it, look up each key in the object's property table,
   check visibility, check type, assign it, and discard the hash table. That's
   a lot of overhead just to assign some properties. With a dedicated inline
   property assignment syntax, a normal bunch of "assign property" bytecode
   instructions can be output and the PHP runtime will cache the property
   offsets and assign them directly, and can elide the property type check if
   the optimiser knows it will pass. HHVM can even burn the property offset
   right into the compiled machine code. That's *way *faster. (At least
   that's how I was told it works when I asked here a couple of weeks ago.)



> --
> Lester Caine - G8HFL
> -
> Contact - http://lsces.co.uk/wiki/?page=contact
> L.S.Caine Electronic Services - http://lsces.co.uk
> EnquirySolve - http://enquirysolve.com/
> Model Engineers Digital Workshop - http://medw.co.uk
> Rainbow Digital Media - http://rainbowdigitalmedia.co.uk
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Alex Duchesne

On 2016-05-31 22: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

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 = ...,
 },
 }
);




Is there anything wrong with casting an array to an object? The syntax 
is almost identical to what you want to achieve.


I can think of three ways to achieve, with the current PHP stable, what 
you seem to desire (forgive me if I misunderstood). Your code becomes:


   $this->fooMethod(
$arg1,
$arg2,
(object)[
'prop1' => ...,
'prop2' => ...,
'prop3' => (object)[
'prop1' => ...,
'prop2' => ...,
},
}
   );


Pretty concise and close to your proposal, right?
Another option is anonymous classes

   $this->fooMethod(
$arg1,
$arg2,
new class {
var $prop1 => ...,
var $prop2' => ...,
var $prop3' => new class {
  var $prop1' => ...,
  var $prop2' => ...,
},
}
   );


Or if you need a specific class name for validation or anything:

$this->fooMethod(
$arg1,
$arg2,
new class extends FooClass {
public $prop1 => ...,
   $prop2' => ...,
   $prop3' => new class extends FooBar {
  public $prop1' => ...,
 $prop2' => ...;
  },
}
);



Last option is a generic class with a __construct taking an array and 
creating a populated instance, which can be used as a base/trait to 
extend dumb classes that only require a name. But you've covered that 
already.



Cheers,



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


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Fleshgrinder
On 6/1/2016 5:47 PM, Ryan Pallas wrote:
> On Wed, Jun 1, 2016 at 9:37 AM, Matt Fonda  wrote:
>>
>>
>> Hi Jesse,
>>
>> It's fairly straightforward to implement a function that does this in
>> userland, for example something like the following:
>>
>> function f($fqcn, $args) {
>> $instance = new $fqcn;
>> foreach ($args as $key => $value) {
>> $instance->$key = $value;
>> }
>> return $instance;
>> }
>> ...
>> $this->fooMethod(
>> $arg1,
>> $arg2,
>> f('FooParams', [
>> 'prop1' => ...,
>> 'prop2' => ...,
>> 'prop3' => f('Obj1', [
>> 'prop1' => ...,
>> 'prop2' => ...,
>> ],
>> ])
>> );
>>
>> You may also use the approach Peter suggested. As such, I don't think
>> introducing a new syntax for it is necessary.
>>
> 
> I disagree here. This lets you add dynamic properties accidentally (by
> putting too many entries in the array or misspelling a property as a key),
> this method does not let IDEs help you with the construction of the array,
> or even what's valid for each value in that array and doesn't provide any
> language level protection against misspelled properties. Of course, for the
> last point, I'm assuming that this idea works like the following:
> 
> class Foo {
>public $prop1;
> }
> 
> new Foo () {
> porp1 = 'foo' // undefined property error of some sort
> };
> 
> 
>> Best,
>> --Matt
>>
> 

Still generically solvable in userland with creativity. :)

  trait ObjectFromArray {

public static function fromArray(array $array, ...$params) {
  $object = new static(...$params);

  foreach ($array as $k => $v) {
if (property_exists($object, $k)) {
  $object->{$k} = $v;
}
else {
  trigger_error('fubar', E_USER_ERROR);
}
  }

  return $object;
}

  }

  class SomeObject {
use ObjectFromArray;

private $foo;

  }

  SomeObject::fromArray(['foo' => 'bar', 'bar' => 'foo']);

-- 
Richard "Fleshgrinder" Fussenegger



signature.asc
Description: OpenPGP digital signature


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Ryan Pallas
On Wed, Jun 1, 2016 at 9:37 AM, Matt Fonda  wrote:
>
>
> Hi Jesse,
>
> It's fairly straightforward to implement a function that does this in
> userland, for example something like the following:
>
> function f($fqcn, $args) {
> $instance = new $fqcn;
> foreach ($args as $key => $value) {
> $instance->$key = $value;
> }
> return $instance;
> }
> ...
> $this->fooMethod(
> $arg1,
> $arg2,
> f('FooParams', [
> 'prop1' => ...,
> 'prop2' => ...,
> 'prop3' => f('Obj1', [
> 'prop1' => ...,
> 'prop2' => ...,
> ],
> ])
> );
>
> You may also use the approach Peter suggested. As such, I don't think
> introducing a new syntax for it is necessary.
>

I disagree here. This lets you add dynamic properties accidentally (by
putting too many entries in the array or misspelling a property as a key),
this method does not let IDEs help you with the construction of the array,
or even what's valid for each value in that array and doesn't provide any
language level protection against misspelled properties. Of course, for the
last point, I'm assuming that this idea works like the following:

class Foo {
   public $prop1;
}

new Foo () {
porp1 = 'foo' // undefined property error of some sort
};


> Best,
> --Matt
>


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Matt Fonda
On Tue, May 31, 2016 at 7:15 PM, 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 = ...,
> },
> }
> );
>
>
> 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
>

Hi Jesse,

It's fairly straightforward to implement a function that does this in
userland, for example something like the following:

function f($fqcn, $args) {
$instance = new $fqcn;
foreach ($args as $key => $value) {
$instance->$key = $value;
}
return $instance;
}
...
$this->fooMethod(
$arg1,
$arg2,
f('FooParams', [
'prop1' => ...,
'prop2' => ...,
'prop3' => f('Obj1', [
'prop1' => ...,
'prop2' => ...,
],
])
);

You may also use the approach Peter suggested. As such, I don't think
introducing a new syntax for it is necessary.

Best,
--Matt


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread guilhermebla...@gmail.com
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 

Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Peter Cowburn
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
>


Re: [PHP-DEV] Set object properties inline

2016-06-01 Thread Lester Caine
On 01/06/16 03:15, Jesse Schalken wrote:
> For large structures, this gets verbose very quick. There is a good example
> of this here
> 
> involving
> 18 unnecessarily variables.
> 
> I can remove the local variables by defining setters for all the properties:

It's nice to see a page of code I can actually read and follow without
having to dig out the 'new functions' crib sheets ...

The main reason I recognise the code is it has elements I was working
with carried over from the PHP4 stuff I started with and I'm still at
the alternate solution ...

$static1   = new Data\StaticVariable;
$static1->name = 'variable name';
$static1->value= $unknown1;
$static1->functionName = 'blahFunction';
$static1->className= null;

Morphed into simply passing an array to the constructor ...

$static1 = new Data\StaticVariable( array(
  'name' => 'variable name',
  'value'=> $unknown1,
  'functionName' => 'blahFunction' ) );

// className defaults to null

Of cause the short cut at that time was to drop the names and simply
count the variables, but what this replaces is all the complications of
named parameters and allowed passing objects in such as '$unknown1'

-- 
Lester Caine - G8HFL
-
Contact - http://lsces.co.uk/wiki/?page=contact
L.S.Caine Electronic Services - http://lsces.co.uk
EnquirySolve - http://enquirysolve.com/
Model Engineers Digital Workshop - http://medw.co.uk
Rainbow Digital Media - http://rainbowdigitalmedia.co.uk

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php