2014-05-27 7 views
4

Я не могу понять, почему это не работает; все три элемента должны быть строками.Неопределенный метод '+ @'

i = 5 
base = "somestring" 
base = i.to_s +" #{base} " + i.to_s # => Undefined method '[email protected]' 

Почему это интерпретируется как метод? Я подумал, что это что-то делать с установкой base равную часть себя, но это похоже на работу:

base = "#{base}" 
+1

Вам нужно пространство между '+' и '" 'в вашей третьей строке –

+0

Wow, потрясающая благодарность Это небольшая деталь. Я думал, что интервал не имеет значения в Ruby? –

+2

Интервал имеет значение в Ruby. Рассмотрим разницу между 'f (x, y)' и 'f (x, y) 'для другого примера. –

ответ

9

Хороший вопрос! В рубине метод [email protected] определяет поведение унарного оператора +. Другими словами, он определяет, что происходит, когда у вас есть выражение типа +someSymbol.

Итак, в этом случае он видит часть вашего выражения, +" #{base} " и пытается применить метод унарного + к строке, которая не существует.

Попробуйте добавить пробел между + и началом вашей строки.


Интересно также, что это происходит только в некоторых случаях.

i = 2 
i.to_s +"foo" # => NoMethodError: undefined method `[email protected]` for "foo":String 
"2" +"foo" # => "2foo" 

Так что же происходит? i.to_s +"foo" эквивалентно i.to_s(+"foo"). И теперь вы можете понять, почему вызывается функция унарного +, а не оператор конкатенации строк.


Итак, у вас есть другие варианты, чтобы исправить код:

i.to_s() +" #{base} " + i.to_s 

или даже

"#{i} #{base} #{i}" 
+0

Отличный ответ! Большое спасибо. Итак, я предполагаю, что интервал действительно имеет значение в Ruby? –

+0

Пробелы не всегда значительны, но в некоторых случаях это определенно. Например, 'obj.method arg0' против' obj.methodarg0' является наглядным примером важности пробелов. Ваш случай - несколько более необычный пример того, где пробелы имеют значение. – JKillian

+2

Это интересно. По крайней мере, 'i.to_s +" foo "' вызывает исключение. Нет такой удачи с '" 4 ".to_i +4 => 0' или' "4" .to_i +6 => 4', что может быть проблемой для отладки. Ваш «или даже» поднял бы глаза, если бы я не видел этого в другом недавнем вопросе. Очень странно. –

2

Добавить пространство вокруг + оператора. В противном случае он рассматривается как унарный + оператора:

i.to_s + "#{base} " + i.to_s 
     ^
Смежные вопросы