Какова логика этого результата?
def foo(_, _='override')
_
end
p foo("bye bye")
p foo("hello", "world")
Вывод:
"override"
"hello"
Я мог понять, был ли результат:
"override"
"world"
или даже:
"bye bye"
"hello"
Но результат, который я получаю, вызывает у меня путаницу.
Ответы
Ответ 1
Аргументы по умолчанию оцениваются раньше времени, чем обычные аргументы, если для него передан аргумент, иначе они оцениваются последним. Почти уверен, но не уверен, как это доказать.
Значение в этом примере:
во время 0 вызов p foo("hello", "world")
в момент времени 1 _ = 'override'
во время 2 _ = "world"
в момент времени 3 _ = "hello"
в 4 раза печатаются переменные, и вы видите "привет"
EDIT вот некоторые доказательства:
def foo(_, _='override',_)
_
end
p foo("bye bye","goodbye")
p foo("hello", "world", "three")
печатает
"override"
"three"
Ответ 2
Я не могу найти лучшего объяснения, чем этот
подчеркивание рубиновой магии
Причиной этого является парсер Rubys в shadowing_lvar_gen. Все нормальные проверки дублирования пропускаются, если имя переменной состоит из ровно одного подчеркивания.
Ответ 3
Одним из возможных объяснений является то, что имя _
означает "неиспользуемая переменная". Вы не должны даже ссылаться на него, не говоря уже о том, чтобы ожидать каких-либо значений. Поскольку это особое имя, он получает специальное лечение от анализатора (например, подавление ошибок "дублирующего параметра" ). Я полагаю, что никто не заботился о том, чтобы этот код вызывал логический результат, потому что опять же это неиспользуемые переменные.
Если вы переименуете его на что-нибудь еще (скажем, a
), вы получите сообщение об ошибке, потому что теперь эта подпись метода не имеет смысла.