_
является действительным идентификатором.Идентификаторы не могут содержать только подчеркивания, они также могут быть подчеркиванием.
_ = o = Object.new
_.object_id == o.object_id
# => true
Вы также можете использовать его как имена методов:
def o._; :_ end
o._
# => :_
Конечно, это не совсем читаемое имя, и при этом он не передает читателю никакой информации о том, на что ссылается переменная или что делает метод.
IRB
, в частности, устанавливает _
в значениепоследнего выражения:
$ irb
> 'asd'
# => "asd"
> _
# => "asd"
Так как в исходном коде , оно просто устанавливает _
в последнее значение:
@workspace.evaluate self, "_ = IRB.CurrentContext.last_value"
Сделал некоторые исследования хранилища.Вот что я нашел:
В последних строках файла id.c
, есть вызов:
REGISTER_SYMID(idUScore, "_");
grep
источник idUScore
дал мне два, казалось бы, релевантных результата:
shadowing_lvar_gen
представляется механизмом, посредством которого формальный параметр блока заменяет переменную с тем же именем, которая существует в другой области видимости.Эта функция вызывает «дублированное имя аргумента» SyntaxError
и предупреждение «теневая внешняя локальная переменная».
После grep
источника shadowing_lvar_gen
я обнаружил следующее в журнале изменений для Ruby 1.9.3 :
вт 11 дек. 01:21:21 2007 Юкихиро Мацумото
- parse.y (shadowing_lvar_gen): нетповторяющаяся ошибка для "_".
Который, вероятно, является источником этой строки :
if (idUScore == name) return name;
Из этого я делаю выводчто в такой ситуации, как proc { |_, _| :x }.call :a, :b
, одна переменная _
просто затеняет другую.
Вот коммит .Он в основном ввел эти две строки:
if (!uscore) uscore = rb_intern("_");
if (uscore == name) return;
С того времени, когда idUScore
, по-видимому, даже не существовало.