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

Reply via email to