Welcome! Log In Create A New Profile

Advanced

[PHP-DEV] New Feature: Fully qualified class name resolution as scalar with class keyword

Posted by Ralph Schindler 
On Wed, Apr 18, 2012 at 1:21 AM, Stas Malyshev <[email protected]> wrote:
> Hi!
>
>> Well, not that you mention it, I don't see a reason why we shouldn't
>> add run-time resolution where necessary. For once this would allow
>
> Runtime resolution of what? We already have get_class(),
> get_called_class() and __NAMESPACE__. Now, having constant expression
> for full class name might be useful since some contexts allow only
> constant expressions. But for runtime contexts we already have it. And
> there's no such thing as run-time resolution of namespaced class names.
Yes, you are right. static::class would be equivalent to
get_called_class() and $foo::class would be equivalent to
get_class($foo).

>> static::class, but also would allow $obj::class. Not sure this is
>> really necessary, but it would be more consistent :)
>
> $obj::class means "class" constant of the class whose name is given by
> string variable $obj. Probably not what you intended. And you have
> get_class() already.
As already mentioned, There can't be a class constant called "class",
because it is a keyword. (const class = 'Foo' is a syntax error).

But yes, I agree that runtime resolution only duplicates existing
behavior, so it isn't really necessary (you could argue thought that
self::class similarly also only replicates the existing __CLASS__). It
would be nice for consistency in my eyes, but I'm good without it too
:)

Nikita

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

> As already mentioned, There can't be a class constant called "class",
> because it is a keyword. (const class = 'Foo' is a syntax error).

It looks like class constant. So it should work like one (or, in this
case, not work since as you noticed there can not be one).

> But yes, I agree that runtime resolution only duplicates existing
> behavior, so it isn't really necessary (you could argue thought that
> self::class similarly also only replicates the existing __CLASS__). It
> would be nice for consistency in my eyes, but I'm good without it too

I do not see any "consistency" in creating functionality that is not
needed and collides with existing syntax and actually works completely
different even though it looks the same. Not much sense to have
$foo::bar and $foo::class mean completely different things. foo::bar is
static constant expression, so is foo::class, but static::class and
$foo::class won't be. It all would be very confusing. I suggest limiting
ourselves to constant expressions like foo::class, self::class and
parent::class.
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On Tue, Apr 17, 2012 at 4:54 PM, Ralph Schindler
<[email protected]> wrote:
> I've also added an RFC page, any thoughts on improving the RFC?
>
>  * https://wiki.php.net/rfc/class_name_scalars
>
> -ralph

What's the state of this RFC?

Nikita

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
I need to address Stas's concerns.

Is there a particular time frame I should be aware of?

-ralph

On 6/19/12 12:19 PM, Nikita Popov wrote:
> On Tue, Apr 17, 2012 at 4:54 PM, Ralph Schindler
> <[email protected]> wrote:
>> I've also added an RFC page, any thoughts on improving the RFC?
>>
>> * https://wiki.php.net/rfc/class_name_scalars
>>
>> -ralph
>
> What's the state of this RFC?
>
> Nikita
>



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

> I need to address Stas's concerns.
>
> Is there a particular time frame I should be aware of?

For 5.5, no rush so far but I imagine we'd want to start figuring out
5.5 feature set in a couple of months, so if you want it there you may
want to have it ready by then.

--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
I'm a bit confused by the "class" keyword in the syntax ClassName::class.
We already have the magic constant __CLASS__ which does exactly the same
class name resolving, if you refer it within the class.

So why to introduce a new keyword instead of using __CLASS__, like
ClassName::__CLASS__?

Eugene

"Ralph Schindler" <[email protected]> wrote in message
news:[email protected]
> Hi all,
>
> There are many different use cases were in code we expect classes names as
> arguments to functions as fully qualified names. We do this in ZF a lot
> with our Service Location and DI components, but also with our code
> reflection API, etc. A more interesting use case I would like to call out
> is with PHPUnit, for example in a test, you might find this:
>
> $mock = $this->getMock('A\Namespaced\ClassName');
>
> This becomes cumbersome when you are dealing with lots of strings about
> lots of class names. This is also an area where, currently, namespace
> declaration and use statements offer no real support.
>
> The patch located here:
>
> https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
>
> ... implements the ability for a developer to leverage the file's
> namespace declaration and use statements to be able to produce a scalar
> (string) of the class name that can be then used, for example, as an
> argument to a function elsewhere.
>
> This overloads the "class" keyword, and by virtue of the existing usage of
> "class" this feature is completely backwards compatible. All existing
> tests pass. For example, the above PHPUnit snipped would become:
>
> use A\Namespaced\ClassName;
> $mock = $this->getMock(ClassName::class);
>
> Another example with reflection:
>
> use SomeOther\FullyNamespaced\ClassElsewhere as CE;
> $r = new ReflectionClass(CE::class);
>
> More examples from the test file:
>
> namespace Foo\Bar {
> class Baz {}
> var_dump(Moo::CLASS); // "Foo\Bar\Moo"
> }
>
> namespace {
> use Bee\Bop as Moo,
> Foo\Bar\Baz;
>
> var_dump(Baz::class); // "Foo\Bar\Baz"
> var_dump(Boo::class); // "Boo"
> var_dump(Moo::CLASS); // "Bee\Bop"
> var_dump(\Moo::Class); // "Moo"
>
> $class = Baz::class; // assign class as scalar to var
> $x = new $class;
> var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
> }
>
>
> What do you guys think?
>
> -ralph



--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
On 2012-07-13, "Eugene Leonovich" <[email protected]> wrote:
> I'm a bit confused by the "class" keyword in the syntax ClassName::class.
> We already have the magic constant __CLASS__ which does exactly the same
> class name resolving, if you refer it within the class.
>
> So why to introduce a new keyword instead of using __CLASS__, like
> ClassName::__CLASS__?


"class" is already a keyword, making it a simpler, easier to remember, and
easier to type choice.


> "Ralph Schindler" <[email protected]> wrote in message
> news:[email protected]
>> Hi all,
>>
>> There are many different use cases were in code we expect classes names as
>> arguments to functions as fully qualified names. We do this in ZF a lot
>> with our Service Location and DI components, but also with our code
>> reflection API, etc. A more interesting use case I would like to call out
>> is with PHPUnit, for example in a test, you might find this:
>>
>> $mock = $this->getMock('A\Namespaced\ClassName');
>>
>> This becomes cumbersome when you are dealing with lots of strings about
>> lots of class names. This is also an area where, currently, namespace
>> declaration and use statements offer no real support.
>>
>> The patch located here:
>>
>> https://github.com/ralphschindler/php-src/commit/02210d51851a96d723fbedcfc64cde9f9ae2b22a
>>
>> ... implements the ability for a developer to leverage the file's
>> namespace declaration and use statements to be able to produce a scalar
>> (string) of the class name that can be then used, for example, as an
>> argument to a function elsewhere.
>>
>> This overloads the "class" keyword, and by virtue of the existing usage of
>> "class" this feature is completely backwards compatible. All existing
>> tests pass. For example, the above PHPUnit snipped would become:
>>
>> use A\Namespaced\ClassName;
>> $mock = $this->getMock(ClassName::class);
>>
>> Another example with reflection:
>>
>> use SomeOther\FullyNamespaced\ClassElsewhere as CE;
>> $r = new ReflectionClass(CE::class);
>>
>> More examples from the test file:
>>
>> namespace Foo\Bar {
>> class Baz {}
>> var_dump(Moo::CLASS); // "Foo\Bar\Moo"
>> }
>>
>> namespace {
>> use Bee\Bop as Moo,
>> Foo\Bar\Baz;
>>
>> var_dump(Baz::class); // "Foo\Bar\Baz"
>> var_dump(Boo::class); // "Boo"
>> var_dump(Moo::CLASS); // "Bee\Bop"
>> var_dump(\Moo::Class); // "Moo"
>>
>> $class = Baz::class; // assign class as scalar to var
>> $x = new $class;
>> var_dump($x); object(Foo\Bar\Baz)#1 (0) {}
>> }
>>
>>
>> What do you guys think?
>>
>> -ralph
>
>


--
Matthew Weier O'Phinney
Project Lead | matthew@zend.com
Zend Framework | http://framework.zend.com/
PGP key: http://framework.zend.com/zf-matthew-pgp-key.asc

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

I think I've addressed some of your concerns and completed this
feature/patch.

https://github.com/php/php-src/pull/187

More inline ...

>> But yes, I agree that runtime resolution only duplicates existing
>> behavior, so it isn't really necessary (you could argue thought that
>> self::class similarly also only replicates the existing __CLASS__). It
>> would be nice for consistency in my eyes, but I'm good without it too

The current patch allows for the following:

self::class -> resolves to name in active_class_entry
static::class -> resolves to FCALL get_called_class()
parent::class -> resolves to FCALL get_parent_class()

I would have liked to have done parent::class w/o FCALL but the
active_class_entry's parent is empty even when inside of a class
extending another class.

> $foo::bar and $foo::class mean completely different things. foo::bar is
> static constant expression, so is foo::class, but static::class and
> $foo::class won't be. It all would be very confusing. I suggest limiting

$foo::class is not syntax that is currently handled (you will get a
parse error: unexpected T_CLASS here. I think that is what you were
ultimately suggesting, no?

Feedback is welcome, either here or in the pull request.

Thanks!
Ralph


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

I still like the proposal.

Am 08.09.2012 um 07:12 schrieb Ralph Schindler <[email protected]>:
[...]
>>> But yes, I agree that runtime resolution only duplicates existing
>>> behavior, so it isn't really necessary (you could argue thought that
>>> self::class similarly also only replicates the existing __CLASS__). It
>>> would be nice for consistency in my eyes, but I'm good without it too
>
> The current patch allows for the following:
>
> self::class -> resolves to name in active_class_entry
> static::class -> resolves to FCALL get_called_class()
> parent::class -> resolves to FCALL get_parent_class()
>
> I would have liked to have done parent::class w/o FCALL but the active_class_entry's parent is empty even when inside of a class extending another class.
>
[...]

What I find absolutely confusing is the use of Class vs. CLASS vs. class for constant names. Let’s limit the translation to FQCN.

cu,
Lars
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
> What I find absolutely confusing is the use of Class vs. CLASS vs. class for constant names. Let’s limit the translation to FQCN.

I will clean up the proposal make the examples more consistent (all lower case). It's worth noting though, that this is reusing the reserved keyword "class" which is case insensitive, so like you class declaration, any casing will work.

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

Am 08.09.2012 um 20:03 schrieb Ralph Schindler <[email protected]>:
[...]
>> What I find absolutely confusing is the use of Class vs. CLASS vs. class for constant names. Let’s limit the translation to FQCN.
>
> I will clean up the proposal make the examples more consistent (all lower case). It's worth noting though, that this is reusing the reserved keyword "class" which is case insensitive, so like you class declaration, any casing will work.

Is see, looks like I misunderstood that part of the proposal as I though you were planning different behavior for different casing.

cu,
Lars
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php
Sorry, only registered users may post in this forum.

Click here to login