Если вы замените email = "bad email"
на self.email = "bad email"
, он будет работать как положено. Это всегда верно при использовании сеттеров.
Причина проста: когда Ruby встречает голое слово, он пытается определить его как локальную переменную. Если его нет, он попытается вызвать метод с таким именем. Внутри тела класса self является неявным получателем, поэтому читатели просто работают. Теперь для писателя есть проблема. Если вы напишите что-то вроде foo = "bar"
, Ruby создаст новую локальную переменную, поэтому вам нужно сделать получатель явным.
Этот случай немного сложнее: if email == "nothing"
использует геттер. Тем не менее, синтаксический анализатор все еще видит email = "bad email"
, а для локальной переменной email
будет установлено значение nil
. Это всегда происходит, когда синтаксический анализатор видит голое слово как LHS назначения. Это локальное значение nil
делает его похожим, что значение email
исчезает (что можно проверить, изменив только последний puts
на puts "End: #{self.email}"
).