irb(main)> foo = true unless defined?(Integer)
=> nil
irb(main)> foo = true unless defined?(thisIsUndefined)
=> true
Ваш первый блок возвращает nil
, потому что способ написания оставляет 2 варианта:
foo
не определено -> назначить true foo
определено -> ничего не делать
Здесь foo должен быть определен при оценке строки.Таким образом, ничего не происходит, и nil
возвращается.
irb(main)> unless defined?(Integer) ; fooo = false ; end
=> nil
irb(main)> unless defined?(thisIsUndefined) ; fooo = false ; end
=> false
Ваш второй блок работает так же, как ваш первый.Если fooo
не определено, вводится блок и fooo
устанавливается на false
.Результатом последней строки блока является возвращаемое значение блока, поэтому вы видите false
.Если fooo
существует, то блок пропускается и ничего не происходит, поэтому возвращать нечего, поэтому nil
.
Основываясь на вашем коде, я бы сказал, что было определено foo
когда этот код был запущен, а fooo
- нет (показанный тестовый код был создан в Ruby 1.8.6).Если вы не определили ни один из них перед запуском этого кода, то у вас может быть что-то с именем foo
, которое определено по умолчанию (для проверки выполните defined?(foo)
самостоятельно).Попробуйте использовать другое имя и посмотрите, получите ли вы те же результаты.
Редактировать:
irb(main)> defined?(bar)
=> nil
irb(main)> bar = true unless defined?(bar)
=> nil
irb(main)> defined?(bar)
=> "local-variable"
По-видимому, defined?()
возвращает значение true, поскольку он уже виделbar
(в начале строки), даже если вы все еще находитесь в процессе его определения.