You’re working on a project with a Ruby style guide that says:
Prefer single quoted strings. Reserve double quoted strings for situations when you need interpolation.
You come across a situation where you need to represent the contracted English word “doesn’t” which contains a single quote. How do you resolve the conundrum? Ruby has lots of ways of handling this. Here are a variety of solutions on a DnD Alignment chart.
Lawful | Neutral | Chaotic | |
---|---|---|---|
Good | 'does not' |
%q{doesn't} |
<<TXT.chomp don't TXT |
Neutral | 'doesn\'t' |
"doesn't" |
"doesn\u{27}t" |
Evil | 'doesn't' |
'doesnt' |
"doesn#{"'"}t" |
Lawful Good
'does not'
This character… er… developer follows the rules but considers what the author might actually be trying to communicate. Maybe we do not need the contraction? Sometimes the best solution doesn’t involve any code but rather re-thinking the requirements.
Lawful Neutral
'doesn\'t'
This developer is looking for an easy way out and doesn’t care about sacrificing
some readability to get there. Why not just escape the offending character? It’s
good enough if used sparingly, although it will make readers do a double-take.
Where does the string start and stop? Are we sure that’s not a tab character
\t
?
Lawful Evil
'doesn't'
What’s another way of representing special characters? I know! HTML entities
The character '
can be expressed as '
. It makes the code harder to read
and might require passing strings through some kind of transformation method
like CGI.unescapeHTML.
It still follows the rules but, depending on the situation, this can feel like a pragmatic trade-off or malicious compliance. It’s the perfect amount of ambiguity 😈
Neutral Good
%q{doesn't}
This developer is practical, while still following the rules. They use the
percent-notation to encode
a string literal without having to overload the meaning of '
. My mnemonic for
remembering which one to use is: little q for little quotes, big Q for double
quotes.
True Neutral
"doesn't"
Meh. The rules exist to serve us, we don’t exist to serve the rules. Just wrap it in double quotes and move on to the next task. This isn’t worth wasting any more time on.
Neutral Evil
'doesnt'
The counterpart to our lawful neutral dev, the neutral evil developer believes this is an English issue, not a Ruby one. They “simplified” the string by removing the problematic apostrophe entirely, leaving us with something not quite right, but not entirely unreadable either. Low-key evil.
Chaotic Good
<<TXT.chomp
don't
TXT
This developer pulled out the heredoc syntax. Normally heredocs are used for larger blocks of multi-line text. It feels a bit intense but it does solve the problem at hand while following the rules. This developer’s heart is in the right place, but they are probably the one who will over-engineer a solution on the project later on down the line.
Chaotic Neutral
'doesn\u{27}t'
This developer heard someone complain about awkward characters in strings and immediately knew the answer - Unicode! Yes, the single quote is part of the basic ASCII set that most people expect to see written in plain text. Did you know that Ruby allows embedding arbitrary unicode code points into a string with the \u{} literal syntax?
What’s that? Single quote is ASCII 39, not 27? That’s because \u{}
takes code
points in hexadecimal, not base 10. Obviously. 🙈
Chaotic Evil
"doesn#{"'"}t"
What’s the creatively worst way we could write this code while still
technically seeming to follow the rules? Well the guideline says double quotes
are allowed when interpolating so what if we interpolated the static character
'
?
So many nested wrappers! Quotes in quotes in braces in quotes. Technically we’re also breaking the rules (inner double quotes wrap a literal, that’s what got us in the mess in the first place) but you didn’t even notice that in all the noise. It’s genius! Evil genius 😈
Conclusion
While this article was mostly a piece of fun, it does pose the question “how do you react when faced with a problem?”. Do you find creative (if somewhat over-engineered) solutions? Do you break the rules? Rethink the requirements? Maybe you do the bare minimum and then move on?
Which developer are you?