Page MenuHomePhabricator

Spaces inside brackets used for array indexing
Open, MediumPublic

Description

https://www.mediawiki.org/wiki/Manual:Coding_conventions/PHP#Spaces states

Put spaces in brackets when declaring an array, except where the array is empty. Do not put spaces in brackets when accessing array elements.

// Yes
$a = [ 'foo', 'bar' ];
$c = $a[0];
$x = [];
 
// No
$a = ['foo', 'bar'];
$c = $a[ 0 ];
$x = [ ];

We already have sniffs that check for $a and $x, but we don't have one for $c. Perhaps we should.

Ideally with a phpcbf fix, because there's probably a fair bit of code where people's IDEs did the "No" version for them.

Event Timeline

Change 588162 had a related patch set uploaded (by Mainframe98; owner: Mainframe98):
[mediawiki/tools/codesniffer@master] Add a sniff to detect and fix whitespace in the array indexer brackets

https://gerrit.wikimedia.org/r/588162

Change 588162 merged by jenkins-bot:
[mediawiki/tools/codesniffer@master] Add Squiz.Arrays.ArrayBracketSpacing to detect spaces in array indexer brackets

https://gerrit.wikimedia.org/r/588162

Since this isn't going to be autofixed (if I understand correctly), sending some patches to fix, eg, https://gerrit.wikimedia.org/r/#/c/mediawiki/core/+/591113/

Umherirrender assigned this task to Mainframe98.
Umherirrender triaged this task as Medium priority.
thiemowmde added subscribers: Krinkle, thiemowmde, daniel.

Wait a second. Are we going to enforce one style now? Where is the discussion if this is a good idea, and how exactly it should be implemented? Why is barely anybody subscribed to this ticket? Why was this ticket never moved to the "accepted" column on the MediaWiki-Codesniffer board?

It's not just me. There are comments at https://gerrit.wikimedia.org/r/591113 asking to not do this, or at least tune it down. Specifically:

While enforcing no spaces for trivial cases like $array[0] or $array['key'] might be fine (or not, see below), we still want to allow spaces in longer constructions like $array[ $this->createKey( $inputValue ) ]. Spaces help a lot making these more readable. And that's what our code sniffer rule set should do: help making code more readable.

Another argument: In JavaScript these spaces are typically enforced, even in simple cases like array[ 0 ]. Why should we enforce the exact opposite here? Why not let the owners of a codebase decide?

Seriously, what's the issue with the extra spaces inside $array[ 0 ]? Personally, I don't use them in trivial cases like this, as argued above. But I don't have a problem reading code that uses these spaces.

I reverted the patch for now. Sorry. We can easily merge it again if we have an agreement.

What @thiemowmde said. I slightly prefer $a[0] to $a[ 0 ], but I much prefer $array[ $this->createKey( $inputValue ) ] over $array[$this->createKey( $inputValue )], and $foo[ $ofs + $i ] over $foo[$ofs + $i].

What @thiemowmde said. I slightly prefer $a[0] to $a[ 0 ], but I much prefer $array[ $this->createKey( $inputValue ) ] over $array[$this->createKey( $inputValue )], and $foo[ $ofs + $i ] over $foo[$ofs + $i].

+1. Integers or short strings look better without space, I prefer "medium-length" strings with spaces but that's just a personal preference, but I think long expressions really deserve the spaces.

I consider array bracket styling as something that does not benefit from blind consistency. Like deciding whether to put a new line between two lines of code, I believe it is best left to the author's choice to decide how closely to group this information in a way that makes the specific code in question easy to digest, balancing which parts should stand out as their own "word" and which should be read together as one.

I would strongly object to a sniff disallowing any spaces (as the above patch did). For non-trivial expressions in array brackets, the space really helps to set these apart as their own "word" which is something authors should continue to be allowed to do if they prefer.

On the other hand, a sniff requiring spaces could work. Although I would mildly prefer we not adopt a sniff that mandates a space there all the time. That has a tendency to remove the ability to express things as one word vs two words which is useful primitive I think. Like the line separation - code organisation is not achieved by adding a blank line after each statement, but rather from letting the other group together expressions as "words" and "sentences".

If others want to continue with a sniff in this category, my suggestion would be to leave simple cases untouched. Thus allowing $foo[0], $foo[$a] and $foo[$a->b] to optionally have a space at the author's discretion/sloppiness - focussing only on the below two:

  • Mistakes - E.g. space on one side but not the other side. Or two spaces instead of one by accicent.
  • Complex expressions - Perhaps a safe threshold could be to say anything involving three or more tokens must have a surrounding space? E.g. $foo[ a( $b, $c ) ], $foo[ $a->b + $c ], $foo[ 1 * 2 * 3 ].

Isn't $a->b already 3 tokens?

I meant three identifiers, not three tokens. My bad. The examples I provided were: 1 func 2 vars, 2 var 1 prop, 3 literal values.

E.g. $foo[ a( $b, $c ) ], $foo[ $a->b + $c ], $foo[ 1 * 2 * 3 ]

Summarising my previous comment:

I don't think we need or benefit from a rule for this. This is akin to how we don't mandate a blank line between every statement, or above every inline comment. Nor do we require $foo->bar()->baz() to be written on separate lines or with spaces. It's at the author's discretion based on what is meant to be seen as one unit, and based on expressing the logic and complexity. See also single-statement lambda's in JavaScript (examples).

However if others prefer, I would not oppose a rule that requires spaces above some kind of complexity threshold. This improve the status quo in that it would help catch and automatically fixup mistakes from inconsistent spacing, and automate the feedback against complex expressions going forward.

Mainframe98 subscribed.
Mainframe98 unsubscribed.

Looks like no progress was made on this task. I think the status quo is not ideal, because the coding conventions require a specific style on which we have no consensus. It looks pretty clear from this discussion that the coding conventions should be updated. Perhaps this example could just be removed; or it could be left just as a suggestion, noting that it should not be enforced. Or maybe we could enforce it (both in the coding conventions and in PHPCS) just for simple literals.