La mayoría son conscientes del _significado especial de 'en IRB como tenedor del último valor de retorno, pero eso no es lo que estoy preguntando aquí.
En cambio, estoy preguntando sobre _cuándo se usa como nombre de variable en código Ruby simple y antiguo. Aquí parece tener un comportamiento especial, similar a una “variable no importa” (à la Prolog ). A continuación, se muestran algunos ejemplos útiles que ilustran su comportamiento único:
lambda { |x, x| 42 } # SyntaxError: duplicated argument name
lambda { |_, _| 42 }.call(4, 2) # => 42
lambda { |_, _| 42 }.call(_, _) # NameError: undefined local variable or method `_'
lambda { |_| _ + 1 }.call(42) # => 43
lambda { |_, _| _ }.call(4, 2) # 1.8.7: => 2
# 1.9.3: => 4
_ = 42
_ * 100 # => 4200
_, _ = 4, 2; _ # => 2
Todos estos se ejecutaron en Ruby directamente (con putss agregados), no en IRB, para evitar conflictos con su funcionalidad adicional.
Sin embargo, todo esto es el resultado de mi propia experimentación, ya que no puedo encontrar ninguna documentación sobre este comportamiento en ninguna parte (es cierto que no es lo más fácil de buscar). En última instancia, tengo curiosidad por saber cómo funciona todo esto internamente para poder comprender mejor exactamente de qué se trata _. Así que estoy pidiendo referencias a la documentación y, preferiblemente, el código fuente de Ruby (y quizás RubySpec ) que revele cómo se _comporta en Ruby.
Nota: la mayor parte de esto surgió de esta discusión con @Niklas B.

lambda { |_, _| _ }.call(4, 2)entre 1.8 y 1.9 es solo un efecto secundario involuntario, entonces. Como en circunstancias "normales" en las que el nombre de la variable no se puede duplicar, el orden en el que se asignan es intrascendente.|_,_,...|porque se ha suprimido el error duplicado._es un identificador válido. Los identificadores no solo pueden contener guiones bajos, también pueden ser un guión bajo._ = o = Object.new _.object_id == o.object_id # => trueTambién puede usarlo como nombres de métodos:
def o._; :_ end o._ # => :_Por supuesto, no es exactamente un nombre legible, ni pasa ninguna información al lector sobre a qué se refiere la variable o qué hace el método.
IRB, en particular, establece_el valor de la última expresión:$ irb > 'asd' # => "asd" > _ # => "asd"Como está en el código fuente , simplemente se establece
_en el último valor:@workspace.evaluate self, "_ = IRB.CurrentContext.last_value"Hice un poco de exploración del repositorio. Esto es lo que encontré:
En las últimas líneas del archivo
id.c, está la llamada:REGISTER_SYMID(idUScore, "_");grepLa fuente deidUScoreme dio dos resultados aparentemente relevantes:shadowing_lvar_genfunciónwarn_unused_varfunciónshadowing_lvar_genparece ser el mecanismo mediante el cual el parámetro formal de un bloque reemplaza a una variable del mismo nombre que existe en otro ámbito. Es la función que parece generar "nombre de argumento duplicado"SyntaxErrory la advertencia "sombreado de variable local externa".Después
grepde buscar la fuenteshadowing_lvar_gen, encontré lo siguiente en el registro de cambios de Ruby 1.9.3 :Cuál es probablemente el origen de esta línea :
if (idUScore == name) return name;De esto, deduzco que en una situación como
proc { |_, _| :x }.call :a, :b, una_variable simplemente ensombrece a la otra.Aquí está el compromiso en cuestión . Básicamente introdujo estas dos líneas:
if (!uscore) uscore = rb_intern("_"); if (uscore == name) return;De una época en la
idUScoreque ni siquiera existía, al parecer.fuente
lambda { |_, _| 42 }funciona mientraslambda { |x, x| 42 }que no.|_, _|funciona, pero|__, __|no._parece tener un significado especial, veré si puedo extraer alguna información de la fuente Ruby.