Re: Wired constant expression syntax and bug
| From: | Julien Pauli | Date: | Tue, 01 Jul 2014 08:26:14 +0000 |
| Subject: | Re: Wired constant expression syntax and bug | ||
| References: | 1 2 3 4 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-75160@lists.php.net to get a copy of this message | ||
On Tue, Jul 1, 2014 at 9:12 AM, Nikita Popov <nikita.ppv@gmail.com> wrote:
> On Tue, Jul 1, 2014 at 7:48 AM, Dmitry Stogov <dmitry@zend.com> wrote:
>>
>> On Tue, Jul 1, 2014 at 1:05 AM, Andrea Faulds <ajf@ajf.me> wrote:
>>
>> >
>> > On 30 Jun 2014, at 20:06, Dmitry Stogov <dmitry@zend.com> wrote:
>> >
>> > > Hi Bob,
>> > >
>> > > I'm wondered why you introduced this wired syntax in PHP-5.6.
>> >
>> > Do you mean weird?
>> >
>>
>> yes :) sorry
>>
>>
>> >
>> > >
>> > > class FooBar {
>> > > const bar = ["bar" => 3]["bar"];
>> > > }
>> > >
>> > > It wasn't a part of RFC, it wasn't covered by tests, and it actually
>> > > doesn't make a lot of sense. May be it's better to remove it?
>> >
>> > I disagree, it makes perfect sense:
>> >
>> > class FooBar {
>> > const FOO = 3;
>> > const BAR = [
>> > 3 => ‘qux’,
>> > 4 => ‘bang’,
>> > 7 => ‘theta’,
>> > 9 => ‘epsilon’
>> > ][FOO];
>> > }
>> >
>> > ?: and ? only work when there are just two possibilities.
>> >
>>
>> ?: may work with brackets, but I have to admit that it's less readable.
>>
>> class Foo {
>> const X = 2;
>> const Y = (Foo::X == 0 ? 1 :
>> (Foo::X == 1 ? 2 :
>> (Foo::X == 2 ? 3 :
>> (Foo::X == 3 ? 4 :
>> 5))));
>> }
>>
>> The situation is really inconsistent because we allow expressions on
>> constant arrays but at the same time prohibit array usage.
>
>
> As we support the [..., ...][...] syntax in normal PHP code as well, I think
> it's reasonable to allow it here as well. Of course it isn't very
> practically useful, but there doesn't seem much point to explicitly
> disallowing it here.
>
>>
>> Look into the following scripts:
>>
>>
>> <?php
>> class Foo {
>> const BAR = [
>> 3 => ‘qux’,
>> 4 => ‘bang’,
>> 7 => ‘theta’,
>> 9 => ‘epsilon’
>> ][1];
>> }
>> var_dump(Foo::BAR); // works - prints 'bang'
>> ?>
>>
>> <?php
>> class Foo {
>> const BAR = [
>> 3 => ‘qux’,
>> 4 => ‘bang’,
>> 7 => ‘theta’,
>> 9 => ‘epsilon’
>> ];
>> }
>> var_dump(Foo::BAR); // doesn't work - Fatal error: Arrays are not allowed
>> in constants at run-time
>> ?>
>>
>> <?php
>> class Foo {
>> const BAR = [
>> 3 => ‘qux’,
>> 4 => ‘bang’,
>> 7 => ‘theta’,
>> 9 => ‘epsilon’
>> ];
>> }
>> // This works again! We may declare array class constants if we don't use
>> them?
>> ?>
>>
>> Where is the logic?
>
>
> The reason here is probably that we cannot detect whether something will be
> an array or not until runtime constant updating. E.g. const BAR = FOO ? 1 :
> [1] or similar. However we might want to detect the case where an array is
> the root of the AST, as that is invalid for sure and the most common case..
>
> Another small issue with the constant expressions I noticed is that our
> recursion detection doesn't properly work for constant ASTs. For example:
>
> <?php
> class A {
> const FOO = [self::BAR];
> const BAR = [self::FOO];
> }
> var_dump(A::FOO);
>
> This will result in a stack overflow instead of a fatal error about
> self-referencing constants.
So what's the status ?
We release RC2 this week. Final is not far, and as I can read, it's not stable.
So I suggest we use more RCs to try to make this stable (and I mean
with OPCache activated).
If we can't make it in reasonnable time, then the feature will have to
be reverted.
Please, note we won't have too many RCs as we are already late on our
original timetable.
Julien Pauli