Hi,
It's a common idiom in object-oriented languages to create an object and
then immediately call a method on it, such as (in C# or Java):
new DateTime ().ToString ()
However, PHP grammar does not work this way. You have to put an additional
round of parentheses around new clause, such as:
(new DateTime ())->format ('Y-m-d')
This is rather clunky for such a common scenario (you usually have to walk
all the way back to the beginning of the expression to fix it). I have a
pattern of using static factories in place of constructor just to avoid
extra parentheses. Besides, the issue is relatively easy to fix. I've done
and tested a change for grammar in this area. It's a slight adjustment to
definition of dereferencable:
dereferencable:
> variable { $$ = $1; }
> | '(' expr ')' { $$ = $2; }
> * | new_expr { $$ = $1; }*
> | dereferencable_scalar { $$ = $1; }
> ;
>
There was a problem with shift/reduces though. PHP has a level of
complexity in new expression which other languages don't. It's variable
class instantiation, such as:
new $class (arguments)
Expressions in place of $class can be rather complex, though I don't think
they really need to be. For example, such stuff is allowed:
new $var[0]->prop (arguments)
— which seems redundant and confusing. My fix to the problem was to force
parentheses around complex expressions such as above:
new ($var[0]->prop) (arguments)
— while keeping simple cases of "new $class (arguments)" without change.
Yes, this moves parentheses from one place to another (and occasionally
breaks the old code) but frequency wise I think it's an improvement.
What do you think?
Jaroslav Wegner