For less screaming in the code

3 years ago by David Grudl  

The Nette coding style is undergoing a minor change: for class constants, the PascalCase notation is now used instead of the original SCREAMING_SNAKE_CASE.

The tradition of using uppercase letters for constants comes from the C language, where so-called macro constants for the preprocessor were marked this way. It was useful to clearly distinguish code for the parser from code for the preprocessor. PHP does not need this distinction since it does not have a preprocessor. On the contrary, excessive highlighting of constants is counterproductive. Why should a constant shout and draw attention to itself, being a prominent element in the flow of the program? There is no reason for it.

An example of real code with SCREAMING_SNAKE_CASE constants that aggressively stand out from the code and are also harder to read:

foreach (self::SYMBOL_TO_NAME as $symbol => $name) {
	$idx = self::ACTION_BASE[$state] + $symbol;
	if (($idx >= 0 && $idx < count(self::ACTION) && self::ACTION_CHECK[$idx] === $symbol
			|| $state < self::YY_2_TBLSTATE
			&& ($idx = self::ACTION_BASE[$state + self::NUM_NON_LEAF_STATES] + $symbol) >= 0
			&& $idx < count(self::ACTION) && self::ACTION_CHECK[$idx] === $symbol)
		&& self::ACTION[$idx] !== self::UNEXPECTED_TOKEN_RULE
		&& self::ACTION[$idx] !== self::DEFAULT_ACTION
		&& $symbol === 0
	) {
		return true;
	}
}

An example of the same code with PascalCase constants, which looks much more compact:

foreach (self::SymbolToName as $symbol => $name) {
	$idx = self::ActionBase[$state] + $symbol;
	if (($idx >= 0 && $idx < count(self::Action) && self::ActionCheck[$idx] === $symbol
			|| $state < self::Yy2Tblstate
			&& ($idx = self::ActionBase[$state + self::NumNonLeafStates] + $symbol) >= 0
			&& $idx < count(self::Action) && self::ActionCheck[$idx] === $symbol)
		&& self::Action[$idx] !== self::UnexpectedTokenRule
		&& self::Action[$idx] !== self::DefaultAction
		&& $symbol === 0
	) {
		return true;
	}
}

Compatibility

Nette, of course, cares about backward compatibility. All public constants remain in their original form and serve as aliases for the preferred PascalCase constants. They will continue to exist in the next major version and will have the @deprecated flag.

All newly added class constants are only available in the PascalCase variant. Global constants are not used by Nette.

Enumerations

PHP 8.1 introduces enumerated types, which will eventually be used in Nette as well. In the past, enums were emulated using constants. The PHP documentation itself uses PascalCase notation for “enum cases”, also PHP-FIG or the earlier experimental implementation SplEnum.

Enums are essentially syntactic sugar for constants; from PHP's perspective, there is no difference between an “enum case” and a class constant. Therefore, combining PascalCase enums and SCREAMING_SNAKE_CASE constants would look inconsistent, which is another reason for changing the constant writing style.

How to change the own code?

Any cosmetic change will always cause a lot of resentment. But if you try using PascalCase constants for a month, you will be thrilled with them and there will be no going back. And you'll want to introduce the new notation into your own code as well. How to do it? The ideal way is to rename the constants in PhpStorm using the Refactor > Rename function. Also, install the plugin String Manipulation and assign it a shortcut in the settings for Switch Case > To Pascal Case.

Then all you have to do is place the cursor on the constant, press Ctrl-F6 (rename) and then the shortcut for To Pascal Case and PhpStorm will change the constant throughout the project.

Happy coding!