Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

String interpolation: don't suggest sprintf() #304

Merged

Conversation

derrabus
Copy link
Member

@derrabus derrabus commented Dec 11, 2022

Our coding standard currently forbids string interpolation and recommends sprintf() or concatenation as alternatives. However, in PHP 7 string interpolation has been optimized and might outperform both alternatives on a hot path.

Of course, we're talking about micro-optimization here and I can totally understand that projects want to stick to sprintf() for the sake of consistency. But I believe that the general recommendation to avoid string interpolation is not up to date anymore.

My proposal is to allow double-quoted interpolated strings.

Update: The PR now removes the suggestion to use sprintf() instead of interpolation.

@derrabus derrabus requested a review from a team as a code owner December 11, 2022 10:08
@derrabus derrabus force-pushed the improvement/allow-string-interpolation branch 3 times, most recently from 2214490 to 87f8cd7 Compare December 11, 2022 10:16
greg0ire
greg0ire previously approved these changes Dec 11, 2022
Copy link
Member

@Ocramius Ocramius left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disagree. The point of disallowing string interpolation is not performance, but maintainability.

While looking for replacements in HEREDOC may sometimes be OK, starting a hunt for variable usages in strings is not.

Overall, string interpolation is to be avoided, IMO.

@greg0ire
Copy link
Member

@Ocramius do you mean that if we enable this, you fear that you are going to have to check every string for variable usages? Because you will only have to do that for strings starting with double quotes? But maybe what you are pointing at is that you don't know how many variables there could be in the string?

@Ocramius
Copy link
Member

Ocramius commented Dec 11, 2022

Let me rephrase: while reading code (human) or analyzing code (machine), I don't want to interpret strings as segments of code that represent anything but constants.

Having to interpret strings as portions of code that include evaluation ("foo $bar baz" and "foo ${bar} ${baz()}") reduces clarity, and requires more effort.

If language features could be removed from PHP, interpolation would certainly be one that should go 👍

This CS ruleset permitted this simplification thus far, and I've been enjoying an interpolation-free ecosystem for a while: let's not reverse that 😁

@Ocramius
Copy link
Member

BTW "foo " . $bar is fine: clear distinction between constant and expression 👍

@derrabus
Copy link
Member Author

The point of disallowing string interpolation is not performance, but maintainability.

I didn't question that. But back when the rule was established, avoiding string interpolation did not have a negative performance impact. Now it does.

Overall, string interpolation is to be avoided, IMO.

Okay, but should it still be forbidden?

Having to interpret strings as portions of code that include evaluation ("foo $bar baz" and "foo ${bar} ${baz()}") reduces clarity, and requires more effort.

I agree and this is what stopped me from suggesting a rule that converts all sprintf() to interpolated strings basically. 😅

Even after my change, double quoted strings would be converted to single quoted ones, so when you actually encounter double quotes, you know that you have to look for interpolation or escape sequences. Also, modern IDEs are pretty good at highlighting interpolation.

Alternatively, can we at least remove the recommendation to use sprintf()?

@Ocramius
Copy link
Member

should it still be forbidden?

Yes, please 🙏

Alternatively, can we at least remove the recommendation to use ssprintf()?

Works for me 👍

@derrabus derrabus force-pushed the improvement/allow-string-interpolation branch from 87f8cd7 to c140fc0 Compare December 11, 2022 15:23
Comment on lines -602 to -604
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<message>Variable "%s" not allowed in double quoted string; use sprintf() or concatenation instead</message>
</rule>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default error message is:

Variable "%s" not allowed in double quoted string; use concatenation instead

No need to override that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the block be kept, or is it just for specifying <message/>?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If was needed for overriding the message. If we don't override the message, the line directly above should be enough:

<rule ref="Squiz.Strings.DoubleQuoteUsage"/>

@derrabus derrabus changed the title Allow string interpolation String interpolation: don't suggest sprintf() Dec 11, 2022
@derrabus derrabus changed the title String interpolation: don't suggest sprintf() String interpolation: don't suggest sprintf() Dec 11, 2022
@derrabus
Copy link
Member Author

Alternatively, can we at least remove the recommendation to use ssprintf()?

Works for me 👍

PR updated. I'm using the default error message now. The new tests are still useful though, so I kept them.

Comment on lines -602 to -604
<rule ref="Squiz.Strings.DoubleQuoteUsage.ContainsVar">
<message>Variable "%s" not allowed in double quoted string; use sprintf() or concatenation instead</message>
</rule>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the block be kept, or is it just for specifying <message/>?

@greg0ire greg0ire added this to the 11.0.0 milestone Dec 11, 2022
@greg0ire greg0ire merged commit b6660e1 into doctrine:11.0.x Dec 11, 2022
@greg0ire
Copy link
Member

Thanks @derrabus !

@derrabus derrabus deleted the improvement/allow-string-interpolation branch December 11, 2022 23:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants