Каков порядок операций с этой конкатенацией?

x = "hello" " world".to_sym
puts x.class

Это работает и позволяет мне объединить две строки в символ, создавая вывод:

Symbol

Но если я немного изменю его, чтобы использовать + вместо пробела, разделяющего строки приветствия и мира, я получу ошибку:

x = "hello" + " world".to_sym
puts x.class

Это приводит к следующей ошибке - я думаю, это потому, что он пытается "привести" вызов "world".to_sym обратно к строке, прежде чем объединить ее со строкой "hello":

in `+': can't convert Symbol into String (TypeError)

Мне интересно, что заставляет работать первый пример? Кто-нибудь знает, каков порядок операций здесь? Я подозреваю, что две строки фактически обрабатываются как одна, что пространство между ними игнорируется и они объединяются до вызова метода to_sym. На самом деле я ожидал, что он будет работать не иначе, как во втором примере, потому что я думал, что to_sym будет вызываться для строки "world" ДО того, как будет предпринята любая попытка соединить содержимое "hello" и "world".

2 ответа

Решение

Два или более строковых литерала, помещенные рядом друг с другом, как это, немедленно обрабатываются как один строковый литерал. Когда интерпретатор Ruby преобразует ваш код в токены, он преобразует

"hello" " world"

на один токен string "hello world" и он преобразует

"hello" + " world"

до трех жетонов: string "hello", method +, а также string " world", Затем он будет объединять строки позже при фактическом выполнении кода.

Первый пример - синтаксический сахар, обычно вы видите это написано так:

x = "Here is a string that " \
    "I want to split across " \
    "several lines..."

Так что это происходит в первую очередь, прежде чем to_sym, Во втором примере вы буквально звоните:

x = "hello".+( "world".to_sym )

Который, очевидно, не будет работать, так как String#+ не могу сделать ничего полезного с символом в качестве аргумента.

Короче, не делай первый, если хочешь "hello world".to_sym и вы не можете просто так написать по какой-то причине, тогда просто используйте круглые скобки: ("hello" + " world").to_sym

Другие вопросы по тегам