2009-05-27 23 views
140

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

line = "first_name=mickey;last_name=mouse;country=usa" 
record = Hash[*line.split(/=|;/)] 

lo entiendo todo en la segunda línea a excepción del operador * - ¿qué está haciendo y dónde está la documentación para esto? (como se puede adivinar, la búsqueda de este caso está resultando difícil ...)

Respuesta

217

El * es el operador splat.

Se expande un Array en una lista de argumentos, en este caso una lista de argumentos para el método Hash.[]. (. Para ser más precisos, se expande cualquier objeto que responde a to_ary/to_a, o to_a en Ruby 1,9)

Para ilustrar, las dos instrucciones siguientes son iguales:

method arg1, arg2, arg3 
method *[arg1, arg2, arg3] 

También se puede utilizar en un contexto diferente, para capturar todos los argumentos de método restantes en una definición de método. En ese caso, no se expande, pero se combinan:

def method2(*args) # args will hold Array of all arguments 
end 

Some more detailed information here.

+33

En general, cuando se utiliza como en una situación similar a LHS (cada vez que se invoca en un valor), splat divide una matriz en valores separados, y cuando se utiliza en una situación similar a RHS (cada vez que ' volver a usarlo en algunas variables no definidas anteriormente), agrupa los valores por separado en una matriz. Entonces 'a, b, * c = d, e, f, * g' establece a = d, b = e, y c = [f, g0, g1, g2, ..., gn], donde g = [ g0, g1, g2, ..., gn] – rampion

+0

excelente respuesta, clara y detallada, gracias –

+2

Para completar, el operador de splat convierte una matriz en una lista vacía según la terminología utilizada en 'The Well Grounded Rubyist' por David A. Negro –

34

El operador splat desempaqueta 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!

4

Como todos mencionan, es un "splat". Buscar la sintaxis de Ruby es imposible, y lo he preguntado en otras preguntas. La respuesta a esa parte de la pregunta es que busca en

asterisk in ruby syntax 

en Google. Google está ahí para ti, simplemente pon lo que ves en palabras.

Anyhoo, como un montón de código de Ruby, ese código es bastante denso. El

line.split(/=|;/) 

hace una serie de seis elementos, first_name, mickey, last_name, mouse, country, usa. Luego, el splat se usa para convertirlo en Hash. Ahora la gente de Ruby siempre te envía a mirar el método Splat, ya que todo está expuesto en Ruby. No tengo idea de dónde está, pero una vez que tenga eso, verá que ejecuta un for a través de la matriz y crea el hash.

Buscaría el código en la documentación core. Si no lo encuentra (no podría), se trataría de escribir algo de código como este (que funciona, pero no es el código Ruby-like):

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 la banda de Ruby será capaz de decirle usted por qué su código es tonto, malo o simplemente erróneo.

Si ha leído hasta aquí, lea a través de la documentación Hash, que no explica el splat, pero sí lo necesita.