A couple months ago, issue #4895 brought forth a great discussion on RuboCop defaults. I think there is (at least) one obvious candidate for a default change. I propose we change the Style/StringLiterals default from single_quotes to double_quotes. This is a style setting I myself have to stay on the look out for and spend a lot of time correcting in my code. I believe using double_quotes consistently is an overall performance boost to developers because moving back and forth between quote styles is unnecessarily complex. Here is an excerpt from @brandonweiss 's article "Always Use Duoble-quoted Strings in Ruby":
If you use both quote styles then every time you make a string you have to think about
which quote style to use. You also have to change the quote style when you add or
remove interpolation from an existing string. If you always use double quotes then you
never have to waste any time thinking about it.
Lawson Kurtz elaborates in more detail in Rubyists: Just use double-quoted strings.. Here are some additional StackOverflow answers with benchmarks as well. The articles and benchmarks highlight that there is no code execution performance gain using either kind of quote. Furthermore, because we can just keep it simple by always using double_quotes, developer performance is improved.
From @ivoanjo 's research of the most downloaded gems, it appears the Ruby community agrees.
The top 4 Ruby gems, bundler, rake, activesupport/rails and thor, all change their Style/StringLiterals default to double_quotes.
It would be nice if someone did a more compelling research on the topic. I'm open to the idea of changing the default, but I also don't want to upset the people happy with it. And, of course, the same argument that's made for single vs double quotes can be extended to all sorts of "semantic" rules floating around the Ruby community. :-)
I scanned the top 130 ruby repos on github based on how many stars the repos have received. All the repos below have 2.3k+ stars, and they are listed in order of greatest to least stars. The repos you don't see are ones not using rubocop OR (less likely) their configuration was in disrepair. Linting was either neglected or never supported in these cases, but someone at sometime squeezed a rubocop.yml into the codebase.
single_quotes/default | double_quotes | disabled
--- | --- | ---
discourse | rails | httparty
gitlabhq | jekyll | hanami
Ruby (spec files) | diaspora | draper (only disabled cop)
spree | homebrew | authlogic
grape | capistrano | errbit
activeadmin | pundit | annotate_models
chef | dotenv
puma | backup
cucumber-ruby | github-changelog-generator
jazzy | fog
twitter | bundler
cancancan | administrate
prawn | celluloid
fat_free_crm | simplecov
reek | stringer
wicked_pdf
byebug
It is more of a split than I thought going in. There are many major repos adopting double_quotes over single, but this is no where near as "obvious" as I originally laid out. double plus disabled do outweigh single. Of course, disabled certainly isn't an endorsement of double_quotes, but it does point out a reluctance to adhere to the default.
I use double quotes exclusively in all my projects, but I am actually not keen on changing the default. Do not underestimate the amount of energy that is ready to be poured into insignificant decisions. Energy which I think could be used much better elsewhere in our community. 馃槈
If it has to be done, please take the path through The Ruby Style Guide, not directly through RuboCop.
@garettarrowood Yeah, there's definitely no consensus in the community. Anecdotally, though, I've found that people who choose double quotes tend to do so because of some or all the reasons I listed in my post, but people who choose single quotes tend to not often have a reason and simply cite RuboCop's default of single quotes as the reason.
Personally, as the author of the post, I'd love the default to switch鈥擨 think defaults like this should evolve over time. People who don't like it can simply configure it back鈥攖hat's the whole point of making it configurable. But to @Drenmi鈥檚 point, there will be a very loud, vocal minority who hate this mostly on principle. I don't mind incurring their wrath (their tears are delicious) but I totally understand people having other hills they'd rather die on.
Great research, @garettarrowood! The results are more or less in line with what I expected (I was only surprised to see projects disabling such a basic cop), so for the time being I think we should not change the default. But you can apply what you did to other of the controversial defaults - maybe for some of them the results would be more clear-cut.
@garettarrowood Nice research, two notes:
You should probably exclude repos with the DisabledByDefault: true config. For example, in activeadmin we actually prefer and use double quotes, but we're using a "DisabledByDefault" approach to introducing Rubocop and we haven't yet enabled the rule.
Byebug has enforced single quotes for a while because of not giving any thought to Rubocop's defaults. However, I switched myself a while ago, and I plan to make the switch in byebug too since it's very frustrating to keep getting style offenses on your own repos... :)
Also did a quick check on ruby/spec. They use DisabledByDefault: true as well, and while enabling double quotes leads to ~16K offenses, enabling single quotes leads to ~51K offenses. So that repo should be either removed from the table or moved to the second column as well.
EDIT: same with puma/puma. DisabledByDefault: true configuration and majoritary style being double quotes (~400 vs ~900 offenses).
EDIT2: same with discourse/discourse. DisabledByDefault: true configuration and majoritary style being double quotes, although in this case the gap is closer (~16K vs ~18K offenses).
EDIT3: Gitlaqhq seems to also disable this cop. Lazy to run the cop there as well but I think this is maybe enough to stop surprising @garettarrowood, and start suprising @bbatsov :)
@deivid-rodriguez - Thank you for these extra details! I'll leave the table above intact so that our comments make sense. However, I will update what you and I find in the table contained below. Since you can vouch for byebug & activeadmin, I'll move them over to double_quotes. While ruby/spec & puma use double quotes more than single, I think we can only safely move them to disabled for now. If we find more in this scenario, perhaps that warrants a 4th column.
single_quotes/default | double_quotes | disabled
--- | --- | ---
spree | rails | discourse
grape | jekyll | gitlabhq
chef | diaspora | Ruby (spec files)
cucumber-ruby | homebrew | puma
jazzy | capistrano | httparty
twitter | activeadmin | hanami
cancancan | pundit | draper (only disabled cop)
prawn | dotenv | authlogic
reek | backup | errbit
wicked_pdf | github-changelog-generator | fat_free_crm
. | fog | annotate_models
. | bundler
. | administrate
. | celluloid
. | simplecov
. | stringer
. | byebug
The most starred Ruby repo that enforces single_quotes is spree. Spree is 17th overall in stars, after rails, jekyll, discourse, gitlabhq, ruby, diaspora, homebrew, and capistrano.
I think discourse and gitlabhq can be moved to disabled too?
Yep. And wow, Gitlab has an extremely intricate rubocop setup. Found the disabling here - https://gitlab.com/gitlab-org/gitlab-styles/blob/master/rubocop-style.yml
Yeah, I got there after jumping from config file to config file too. :laughing:
One more - fat_free_crm has this rule explicitly disabled as well - must have just missed it.
I'd say that if the community is this split on the rule, maybe it should be disabled by default, rather than the default changed?
And then in a few months it could be re-reviewed until there was general consensus and then that consensus be re-added as either of the options :)
I'd say that if the community is this split on the rule, maybe it should be disabled by default, rather than the default changed?
For newcomers it would be like this doesn't exist (few people go browsing disabled cops), so I don't like this idea.
For newcomers it would be like this doesn't exist
Yeah, consistency within a codebase is more important than which option is picked.
My 2 cents on this topic: I've been using the default and not thinking about it too much. There always seemed to be sufficient arguments on both sides of this debate. Reconsidering again, I think I'll switch to double quotes on new projects.
Changing the default seems like it might generate significant noise, mostly directed at @bbatsov. So my vote is with him. If he can be convinced that it is worth it, great.
I like double quotes for string that is literally string like
@error = "ERROR, password can't be blank"
notice: "User was successfully created."
but I prefer single quotes for things like
require 'libraryname'
ENV['variablename']
File.expand_path('../../Gemfile', __FILE__)
can we get both?
@buncismamen That's a very specific, unusual style. I think it would be very difficult to enforce different quote styles in different usage-contexts. And then, beyond how difficult it would be, this is probably not a common enough style that it would merit adding an entire configuration option for.
Let's just close this, as it seems there's no strong reason to make the change and just frustrate many people. I guess whoever cares about the string literals has already changed the default anyways.
I know this is already closed but just one point that wasn't made:
Editors I use such as Vim are significantly slowed down by checking double quoted strings in order to find any interpolations inside of them. In a string heavy file like a big dump of data this can cause a noticable lag which %s/"/'/g magically fixes.
@puyo Hmm, I never thought about this, but it's a valid point. Many editors just look for the interpolation using regular expressions (Emacs as well), which is not very cheap.
Late to the party, but I ran across this discussion and it seems to not have a lot of single-quote supporters, so here's my 2c. I had the rule disabled because I didn't care, and slowly moved to single quotes because I like slapping ' without shift. It sounds silly, I know, but putting quotes around stuff is such a common thing that one less modifier to hold is a small typing speed/comfort improvement. Also, as a vim user, changing from single to double quotes is a simple cs'" from anywhere inside a string.
I didn't mean to switch to ', or to care, but laziness won apparently.
I like double quotes for string that is literally string like
@error = "ERROR, password can't be blank"
notice: "User was successfully created."but I prefer single quotes for things like
require 'libraryname'
ENV['variablename']
File.expand_path('../../Gemfile', __FILE__)can we get both?
Python too has this super widespread implicit convention that single quotes are for computers and double quotes for human, see https://stackoverflow.com/a/56190/1765357 (but it doesn't necessarly mean Ruby should have it too)
FWIW - earlier this year RuboCop's users voted on the subject and the chose single-quoted literals https://metaredux.com/posts/2020/05/26/rubocop-defaults-survey-results.html For now this topic is closed as far as I'm concerned.
Most helpful comment
Research
I scanned the top 130
rubyrepos on github based on how many stars the repos have received. All the repos below have 2.3k+ stars, and they are listed in order of greatest to least stars. The repos you don't see are ones not using rubocop OR (less likely) their configuration was in disrepair. Linting was either neglected or never supported in these cases, but someone at sometime squeezed arubocop.ymlinto the codebase.single_quotes/default |double_quotes| disabled--- | --- | ---
discourse | rails | httparty
gitlabhq | jekyll | hanami
Ruby (spec files) | diaspora | draper (only disabled cop)
spree | homebrew | authlogic
grape | capistrano | errbit
activeadmin | pundit | annotate_models
chef | dotenv
puma | backup
cucumber-ruby | github-changelog-generator
jazzy | fog
twitter | bundler
cancancan | administrate
prawn | celluloid
fat_free_crm | simplecov
reek | stringer
wicked_pdf
byebug
Conclusion
It is more of a split than I thought going in. There are many major repos adopting
double_quotesover single, but this is no where near as "obvious" as I originally laid out.doubleplus disabled do outweighsingle. Of course, disabled certainly isn't an endorsement ofdouble_quotes, but it does point out a reluctance to adhere to the default.