6

I was setting up symbols in my code like:

"name_of_symbol".to_sym

However, my principal engineer picked it up during code review as a bad practice and asked me to set symbols like:

:"name_of_symbol"

When I asked him why? He said it's bad practice, but when I asked for what reason he just said it is, which is not really a satisfying answer. So how is it? Is there any difference at all?

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
Jakub Zak
  • 1,212
  • 6
  • 32
  • 53
  • 5
    It seems to be the convention at your workplace, not so much a question of one being a "bad practice". Conventions are just that, no need to argue (why do we call a "tree" a "tree" and not a "gluff"? Because we agreed to use "tree"). Some may argue "readability" - but without having done an actual scientific study to prove that :sym syntax is easier to read it's just a claim. On the other hand, if the guy refused to give an explanation that's something we cannot help you with :( My take: define a symbol with `:sym`, but for an explicit conversion to symbol use `.to_sym`. – Mörre Dec 30 '14 at 15:56
  • 4
    It isn't bad practice. Bad practice is to be unable to explain something when you are team lead on project. – Rustam Gasanov Dec 30 '14 at 16:04
  • It isn't a good practice either. Note that you don't neet quotes if your symbol doesn't contain whitespaces and other characters that could be ambiguously interpreted by Ruby parser. So `:foo_bar` is OK without quotes, you only need quotes for `:"foo bar"`. – Boris Stitnicky Dec 30 '14 at 17:26
  • 2
    I'm trying to think of a justification for the PE's answer. Perhaps the PE didn't have time for an explanation, but then he/she could have said (sic), "I'll explain when I have time." My suspicious nature equates "it's bad practice" with "I don't know." Many people seem incapable of mouthing those last three words, failing to understand that their standing among their peers would improve if they could do so. – Cary Swoveland Dec 30 '14 at 21:25

4 Answers4

6

The colon indicates a symbol. I wouldn't call it bad practice so much as unconventional practice, which might make the code a little harder to understand.

I know that :"Some weird stuff" is legal but don't like it, personally I'd rather use :Some_weird_stuff and leave the quotes out all together - using quotes when you don't need to is just adding noise - I'm very anti-noise. Noise is bad practice, it makes understanding take longer.

Sometimes, when you're matching things that came in as strings but for consistency you want symbols then you don't have much choice, but I prefer not to have to ask this question, FWIW.

When you have syntactically clean symbols you can use the

{ thing: "value" }

syntax, which is a joy and very clear and uncluttered.

Interestingly, though:

irb
> class String ; def to_sym ; puts "bob" ; end ; end
  => nil
> "fred".to_sym
  bob
  => nil
> :"fred"
  => :fred

So Boris' point is a valid one.

Ghoti
  • 2,388
  • 1
  • 18
  • 22
  • I should probably note in my question that its for times when symbol is being set dynamically like array.each{|s| :"#{s}" } so by my way it would be "#{s}".to_sym – Jakub Zak Dec 30 '14 at 15:54
  • 4
    So you've got a string and you're doing :"#{s}" - personally I'd go with to_sym, interpolating a string and then calling to_sym on the fly in the background ... a bit pointless, I think :) – Ghoti Dec 30 '14 at 15:55
  • 3
    In other words, don't do `:"#{s}"` or `"#{s}".to_sym`, just do `s.to_sym` – Ajedi32 Dec 30 '14 at 16:12
  • :"#{s}" guarantees you will get the symbol you expect, even if someone has messed with the String class' to_sym - so it's safer. Why someone would do that for reasons other than being an annoying person is a different question :) – Ghoti May 08 '15 at 10:13
4

One is a Symbol literal, the other is a String literal upon which you call a method.

Personally, I find it weird to write a String when you mean to write a Symbol, only to then immediately convert the String into a Symbol. Why not write a Symbol in the first place? That makes your intentions much clearer.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653
  • 1
    It isn't weird, for example, if some method returns a string, then `method_which_returns_a_string.to_sym` is way to go – Rustam Gasanov Dec 30 '14 at 16:26
  • @RustamA.Gasanov: but that's not what this question is about. The question is about using a symbol literal directly as opposed to a string literal which then gets converted to a symbol. Obviously, a completely different question may have a completely different answer. – Jörg W Mittag Dec 30 '14 at 16:29
3

Other answers argue correctly that :"foo bar" is superior to "foo bar".to_sym because it is clearer, better expresses your intention, is more readable, faster etc. But there is one more reason: "foo bar".to_sym relies on String#to_sym method, and there is a possibility (although remote) that this method might be redefined. This is the one non-cosmetic reason why :"foo bar" is in principle better practice.

Boris Stitnicky
  • 12,444
  • 5
  • 57
  • 74
2

This seems like a matter of preference but I can see how writing a symbol as a symbol is a lot clearer than writing a string that you're changing into a symbol.

Also, the quote marks are unnecessary when you're using snake_case.

  1. "name_of_symbol".to_sym
  2. :"name_of_symbol"
  3. :name_of_symbol

This is a matter of style but it seems to me that 3 is the most readable and concise version of the three. If "best practice" means easy to read and therefore maintain, I'd say 3 wins.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
benjaminjosephw
  • 4,369
  • 3
  • 21
  • 40