¿Qué hace el operador (unario) * en este código Ruby?
Dado el código Ruby
line = "first_name=mickey;last_name=mouse;country=usa"
record = Hash[*line.split(/=|;/)]
Entiendo todo lo que aparece en la segunda línea, excepto el *
operador: ¿qué está haciendo y dónde está la documentación al respecto? (Como puedes imaginar, buscar este caso está resultando difícil...)
Es *
el operador splat .
Expande Array
una lista de argumentos, en este caso una lista de argumentos del Hash.[]
método. (Para ser más precisos, expande cualquier objeto que responda a to_ary
/ to_a
, o to_a
en Ruby 1.9.)
A modo de ilustración, las siguientes dos afirmaciones son iguales:
method arg1, arg2, arg3
method *[arg1, arg2, arg3]
También se puede utilizar en un contexto diferente, para capturar todos los argumentos restantes del método en una definición de método. En ese caso, no se expande, sino que combina:
def method2(*args) # args will hold Array of all arguments
end
Alguna información más detallada aquí .
El operador splat descomprime una matriz pasada a una función para que cada elemento se envíe a la función como un parámetro individual.
Un ejemplo sencillo:
>> def func(a, b, c)
>> puts a, b, c
>> end
=> nil
>> func(1, 2, 3) #we can call func with three parameters
1
2
3
=> nil
>> list = [1, 2, 3]
=> [1, 2, 3]
>> func(list) #We CAN'T call func with an array, even though it has three objects
ArgumentError: wrong number of arguments (1 for 3)
from (irb):12:in 'func'
from (irb):12
>> func(*list) #But we CAN call func with an unpacked array.
1
2
3
=> nil
¡Eso es todo!
Como todo el mundo menciona, es un "splat". Buscar la sintaxis de Ruby es imposible y lo he hecho en otras preguntas. La respuesta a esa parte de la pregunta es que buscas en
asterisk in ruby syntax
en Google. Google está ahí para ayudarte, simplemente expresa con palabras lo que ves.
De todos modos, como gran parte del código Ruby, ese código es bastante denso. El
line.split(/=|;/)
forma una serie de SEIS elementos first_name, mickey, last_name, mouse, country, usa
. Luego, el símbolo se usa para convertirlo en un Hash. Ahora la gente de Ruby siempre te manda a mirar el método Splat, ya que todo está expuesto en Ruby. No tengo idea de dónde está, pero una vez que lo tenga, verá que recorre for
la matriz y genera el hash.
Buscaría el código en la documentación principal . Si no puede encontrarlo (yo no pude), intentaría escribir un código como este (que funciona, pero NO es un código similar a Ruby):
line = "first_name=mickey;last_name=mouse;country=usa"
presplat = line.split(/=|;/)
splat = Hash.new
for i in (0..presplat.length-1)
splat[presplat[i]] = presplat[i+1] if i%2==0
end
puts splat["first_name"]
y luego Ruby podrá decirte por qué tu código es tonto, malo o simplemente incorrecto.
Si ha leído hasta aquí, lea la documentación de Hash para la inicialización.
Básicamente, un hash que se inicializa con varios argumentos los crea como pares clave-valor:
Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
Entonces, en su ejemplo, esto conduciría al siguiente Hash:
{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}