¿Qué hace el operador (unario) * en este código Ruby?

Resuelto David Burrows asked hace 15 años • 3 respuestas

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...)

David Burrows avatar May 28 '09 06:05 David Burrows
Aceptado

Es *el operador splat .

Expande Arrayuna 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_aen 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í .

molf avatar May 27 '2009 23:05 molf

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!

BJ Homer avatar May 27 '2009 23:05 BJ Homer

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 forla 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"}
Dan Rosenstark avatar May 28 '2009 00:05 Dan Rosenstark