Req #71419 [Com]: Allow ::new() syntax.

From: Date: Mon, 01 Feb 2016 16:00:11 +0000
Subject: Req #71419 [Com]: Allow ::new() syntax.
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-198990@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=71419&edit=1

 ID:                 71419
 Comment by:         willfitch@php.net
 Reported by:        andreas at dqxtech dot net
 Summary:            Allow ::new() syntax.
 Status:             Open
 Type:               Feature/Change Request
 Package:            Class/Object related
 PHP Version:        7.0.2
 Block user comment: N
 Private report:     N

 New Comment:

> Proposal: Allow a syntax "C::new()", which would be equivalent to "(new
> C())"

You're asking for a factory method as a built-in language construct/feature. While I won't
assume your situation warrants this in your opinion, I have/can never imagine why this is warranted.
If your reasoning lies strictly on method chaining, static methods (factory or not) is a language
feature you should use.

The primary difference between "C::new()" and "(new C())" is one character less
in length.  Looking at this from a purely language perspective, you're essentially asking for
an exception to a static method call.  At best, that will lead to a slippery-slope (e.g. I'd
like C::delete to call C::__destruct - even though I can just use $instance = null or
unset($instance)).

If you feel strongly about this, you should write up an RFC, and put it out there for discussion. 
You won't get much traction in the bugs area.


Previous Comments:
------------------------------------------------------------------------
[2016-01-25 15:54:49] andreas at dqxtech dot net

I think before accepting the RFC it would have been a good idea to check which of these reserved
words could have a useful meaning with "::", and thus, which doors are being closed by
allowing these keywords as method names.

E.g. for C::while() I don't really see anything useful other than interpreting it as a method.
So it is fine to make "while" a valid method name.

For C::new(), this could be an alternative syntax for "new C()". So maybe a good idea to
keep this reserved..

C::class already has a meaning. C::namespace could be given a meaning.

For now, C::new() is the only one that sticks out to me for method syntax.

------------------------------------------------------------------------
[2016-01-25 15:44:49] andreas at dqxtech dot net

Thanks for the RFC link!

> Anyway, you could use a trait to make your wished pattern easier to implement (on 7.0+):

Sure.. but of course the idea here was to make this a language feature, so it would work for all
classes, including those from 3rd party libraries, where I cannot add a "use Newable".

I guess it is not going to happen.

------------------------------------------------------------------------
[2016-01-25 15:36:38] wegvonhier+phpbugs at gmail dot net

I believe the correspondig rfc for that change is this one: https://wiki.php.net/rfc/context_sensitive_lexer
(allowing reserved words such as new in more contexts, the rfc even has an example using
Collection::new()->method())

Anyway, you could use a trait to make your wished pattern easier to implement (on 7.0+):

https://3v4l.org/ZQLSk

------------------------------------------------------------------------
[2016-01-20 13:06:05] andreas at dqxtech dot net

Description:
------------
I often create classes that have a normal constructor, and one or more static factory methods.

On instantiation, I need to decide between "new C()" and "C::create()".
For method chaining, the "new C()" needs additional brackets, like so: "(new
C())".

Switching between the two notations can be annoying.

Proposal: Allow a syntax "C::new()", which would be equivalent to "(new C())".

--------

Now.. when I had this idea, I was not aware that since PHP 7, and also in hhvm, it is possible to
name a method like "new()".
https://3v4l.org/Pp68v with user-defined method new().
https://3v4l.org/YvjJ9 without such a method.
This is unfortunate, and makes this request difficult, if not impossible.

A remaining (but not really great) option would be to give every class an "implicit"
static method ::new(), but allow this method to be overridden.

Maybe this was already discussed and discarded, and this is the reason why a method named
"new()" is now allowed. In this case I would like this to be considered a support request.
The answer could be a link to the discussion where this was decided.

Test script:
---------------
<?php

class C {}

class D {

  /**
   * Allowed since PHP 7
   */
  static function new() {return NULL;}
}

// Call implicit method new, equivalent to "new C()";
$instance = C::new();
assert($instance instanceof C);

// Call explicit method new.
$null = D::new();
assert($null === null);



------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=71419&edit=1


Thread (11 messages)

« previous php.bugs (#198990) next »