0

eg, :"foo" vs :foo.

More specifically, if I have a string like "Clarinet (B♭)", and I call .to_sym on it, I get a quoted symbol, with escaped chars: :"Clarinet (B\342\231\255)". In this instance, I would like to use the string version of it rather than the symbol version, as a hash key. More generally, if I get any quoted symbol, I want to not use the symbol at all and just use the original string.

eg

ahash = {}
s = "Clarinet (B♭)"
sym = s.to_sym
if some_test_for_quoted_symbols
  ahash[sym] = "foo"
else
  ahash[s] = "foo"
end

Does anyone know how I can distinguish between symbols with or without quotes? Thanks

PS please don't tell me I shouldn't be using such an old version of Ruby. thanks!

Max Williams
  • 32,435
  • 31
  • 130
  • 197
  • 2
    why not use strings always then? – Sergio Tulentsev Jun 17 '19 at 13:56
  • 8
    `:foo` and `:"foo"` are identical. If you want to distinguish characters that will need to be escaped, that's one thing, but you're not going to be able to distinguish `:foo` and `:"foo"`. – khelwood Jun 17 '19 at 13:57
  • 1
    Well, `if sym.inspect[1] == '"'` obviously would work, but you shouldn't do it in the first place. – Stefan Jun 17 '19 at 14:03
  • @Stefan: that would give false positives. `:"foo bar"`, for example. – Sergio Tulentsev Jun 17 '19 at 14:08
  • 2
    @SergioTulentsev why is that a false positive? – Stefan Jun 17 '19 at 14:09
  • 4
    This question screams "*AB problem!*" to me. There is no such thing as a "quoted symbol" in ruby; it's purely a means of displaying the value clearly in your terminal; similar to how `\n` gets displayed in place of invisible whitespace. **Why** do you want to check if the symbol contains a space? What problem are you actually trying to solve? – Tom Lord Jun 17 '19 at 14:19
  • @Stefan: because no escaped chars? – Sergio Tulentsev Jun 17 '19 at 14:22
  • @TomLord it's more about increasing my understanding than solving a specific problem, really. – Max Williams Jun 17 '19 at 14:26
  • @MaxWilliams A symbol can contain any characters. However, it wouldn't make sense to define a symbol as `:foo bar` -- since that syntax appears to mean `:foo`, followed by a variable/method `bar`. Therefore one must declare the symbol as `:"foo bar"`, or `"foo bar".to_sym`. That's all. `:foo` and `:"foo"` are literally the same object. – Tom Lord Jun 17 '19 at 14:47
  • @SergioTulentsev of course, `sym.inspect[1] == '"'` doesn't check for escaped characters. It merely checks whether that symbol needs to be quoted when given as a literal. – Stefan Jun 17 '19 at 14:53

1 Answers1

0

Like khelwood said in the comments symbols with or without quotes are identical.

:foo == :"foo" #=> true

The reason Ruby displays some symbols with and other symbols without quotes is due to their content. Symbols that are conform the standards of methods names will be displayed without quotes, while symbols that don't conform to the format are displayed with quotes.

Meaning that:

# operators are displayed without quotes
:">>" #=> :>>
# snake case naming will be displayed without quotes
:"foo_bar" #=> :foo_bar

# symbols starting with a number will be displayed with quotes
:"8bit" #=> :"8bit"
# symbols with certain characters will be displayed as quoted
:"foo-bar" #=> :"foo-bar"
:"foo bar" #=> :"foo bar"
:"null_byte_\0" #=> :"null_byte_\x00"

Method Names

Method names may be one of the operators or must start a letter or a character with the eight bit set. It may contain letters, numbers, an _ (underscore or low line) or a character with the eight bit set. The convention is to use underscores to separate words in a multiword method name:

def method_name
  puts "use underscores to separate words"
end

Ruby programs must be written in a US-ASCII-compatible character set such as UTF-8, ISO-8859-1 etc. In such character sets if the eight bit is set it indicates an extended character. Ruby allows method names and other identifiers to contain such characters. Ruby programs cannot contain some characters like ASCII NUL (\x00).

The following are examples of valid Ruby methods:

def hello
  "hello"
end

def こんにちは
  puts "means hello in Japanese"
end

Typically method names are US-ASCII compatible since the keys to type them exist on all keyboards.

Method names may end with a ! (bang or exclamation mark), a ? (question mark), or = (equals sign).

3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
  • That makes sense, thanks. Is there an inbuilt way to test if a string is allowable as a method name? Because if so then I could use that. Obviously I could write a regex to do it but i'd rather use something inbuilt if possible. – Max Williams Jun 18 '19 at 10:16
  • This question asks the same thing (variable name, not method name, but I think the rules are the same), and the test is to basically try to use it as a variable name and if it explodes, then you catch it and decide it's not valid. Feels a bit not-clean. – Max Williams Jun 18 '19 at 10:18
  • 1
    If you wan't to keep you code clean, don't mix and match types. Symbols and strings have different jobs to fulfil. I recommend taking a look at: [When to use symbols instead of strings in Ruby?](https://stackoverflow.com/questions/16621073/when-to-use-symbols-instead-of-strings-in-ruby). If you still for some reason want to check if the representation of the symbol would be quoted have a look at [Stefan's comment](https://stackoverflow.com/questions/56632779/how-in-ruby-1-8-6-to-differentiate-between-regular-symbols-and-quoted-symbol/56633652?noredirect=1#comment99837660_56632779). – 3limin4t0r Jun 19 '19 at 07:06