Каков порядок операций с этой конкатенацией?
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