Re: [RFC]
| From: | Rowan Tommins | Date: | Thu, 13 Feb 2020 13:17:27 +0000 |
| Subject: | Re: [RFC] | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-108538@lists.php.net to get a copy of this message | ||
On Thu, 13 Feb 2020 at 12:04, Manuel Canga <manuelcanga@gmail.com> wrote:
>
>
> On Thu, 13 Feb 2020 at 08:58, Rowan Tommins <rowan.collins@gmail.com>
> wrote:
>
>> On 12 February 2020 23:12:34 GMT+00:00, Manuel Canga <
>> manuelcanga@gmail.com> wrote:
>> >El mié., 12 feb. 2020 23:01, Rowan Tommins <rowan.collins@gmail.com>
>> >escribió:
>> >In your example, you has the same options:
>> >
>> >>
>> >1. Change import
>> >2. Add namespace:
>> >
>> >['Acme\Global\I18N',\translate::function]
>>
>>
>> There is no collision between 'Foo::translate()' and 'translate()', so
>> there is no reason to change the import. That's true of executing the
>> functions, so it should remain be true of resolving them to strings.
>>
>> There is collision with import which you added.
>
There is no collision. This is perfectly valid PHP code:
namespace Foo;
use \explode;
class Bomb { public static function explode() { return 'Bang! Bang!'; } }
$bangs = explode(' ', Bomb::explode());
There is no ambiguity here, explode(...) refers precisely to the global
function 'explode' which is unrelated to the class method 'Bomb::explode'.
The same applies if I import the function from somewhere other than the
global namespace:
namespace Foo;
use Acme\BetterArrayFunctions\explode;
class Bomb { public static function explode() { return 'Bang! Bang!'; } }
$bangs = explode(' ', Bomb::explode());
Again, there is no ambiguity, explode(...) refers precisely to the function
'Acme\BetterArrayFunctions\explode, which is unrelated to the class method
'Bomb::explode.
"explode::function" should mean "if I run explode() here, what is the
fully-qualified name of the function that would run?" If there's no
ambiguity of which function would run, there's no ambiguity of what value
::function should return.
> * Here, 'my_function' is only a string. Maybe a global function( without
> namespace ) or maybe a method or other case. With native array_map is a
> global function. However, you can have a function like this:
>
> function array_map( $method, $array) {
> \Collection::$method( $array );
> }
>
> In both cases, you could do:
>
> array_map(\my_function::function, [] );
>
In the second case, it would be incorrect to use \my_function::function,
because you do not want the answer to the question "if I run \my_function()
here, what is the fully-qualified name of the function that would run?"
Annotating the argument that way wouldn't be useful for tools, either -
e.g. an IDE like PHPStorm would see ::function and offer "jump to
definition", but in this case it would jump to the definition of the global
function my_function, which is actually irrelevant.
>
>
>> Importantly, it might not work at all, if ::function gives an error if
>> the function doesn't exist.
>>
>>
> ::function only would retrieve string, like as ::class, exists or not. In
> fach, that code might not work at all due to class. What matter if Class
> does't exist ?. ::class doesn't produce error. Look:
>
> http://sandbox.onlinephpfunctions.com/code/0a8466a00974bc1ffc12b219569ced55753327bd޶zü
> 2Z0x`ÁN€Ëý
>
As pointed out elsewhere, an implementation of ::function would need to be
smarter than ::class, because unqualified function calls look first in the
current namespace, then fall back to global scope. For example:
namespace Foo;
function explode() {}
echo implode::function; // Should return 'implode', because that is what
implode() would run
echo explode::function; // Should return 'Foo\explode', because that is
what explode() would run
Regards,
--
Rowan Tommins
[IMSoP]