Que fait l'opérateur (unaire) * dans ce code Ruby?


174

Compte tenu du code Ruby

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

Je comprends tout dans la deuxième ligne à l'exception de l' *opérateur - que fait-il et où se trouve la documentation à ce sujet? (comme vous pouvez le deviner, la recherche de cette affaire s'avère difficile ...)

Réponses:


271

Le *est l' opérateur splat .

Il développe an Arrayen une liste d'arguments, dans ce cas une liste d'arguments de la Hash.[]méthode. (Pour être plus précis, il étend tout objet qui répond à to_ary/ to_a, ou to_adans Ruby 1.9.)

Pour illustrer, les deux déclarations suivantes sont égales:

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

Il peut également être utilisé dans un contexte différent, pour capturer tous les arguments de méthode restants dans une définition de méthode. Dans ce cas, il ne se développe pas, mais combine:

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

Quelques informations plus détaillées ici .


36
En général, lorsqu'il est utilisé comme dans une situation de type LHS (chaque fois que vous l'appelez sur une valeur), splat divise un tableau en valeurs séparées, et lorsqu'il est utilisé dans une situation de type RHS (chaque fois que vous l'utilisez sur certaines variables précédemment non définies), il regroupe des valeurs séparées dans un tableau. Donc a,b,*c = d,e,f,*gdéfinit a = d, b = e et c = [f, g0, g1, g2, ..., gn], où g = [g0, g1, g2, ..., gn]
rampion

2
Juste pour être complet, l'opérateur splat transforme un tableau en une liste nue selon la terminologie utilisée dans 'The Well Grounded Rubyist' de David A. Black
David Burrows

12
@rampion: Merveilleux commentaire, vous venez de mélanger LHS et RHS. C'est l'inverse.
ThomasH

47

L'opérateur splat décompresse un tableau passé à une fonction afin que chaque élément soit envoyé à la fonction en tant que paramètre individuel.

Un exemple simple:

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

C'est tout!


6

Comme tout le monde le dit, c'est un «splat». La recherche de la syntaxe Ruby est impossible, et je l'ai posé dans d'autres questions. La réponse à cette partie de la question est que vous recherchez

asterisk in ruby syntax

dans Google. Google est là pour vous, mettez simplement ce que vous voyez en mots.

Quoi qu'il en soit, comme beaucoup de code Ruby, ce code est assez dense. le

line.split(/=|;/)

rend un réseau d'éléments SIX, first_name, mickey, last_name, mouse, country, usa. Ensuite, le splat est utilisé pour en faire un Hash. Maintenant, les gens de Ruby vous envoient toujours regarder la méthode Splat, puisque tout est exposé dans Ruby. Je n'ai aucune idée de l'endroit où il se trouve, mais une fois que vous l'avez, vous verrez qu'il parcourt forle tableau et construit le hachage.

Vous recherchez le code dans la documentation principale . Si vous ne pouvez pas le trouver (je ne pourrais pas), vous essayez d'écrire un code comme celui-ci (qui fonctionne, mais n'est PAS du code de type 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"]

et ensuite le gang Ruby pourra vous dire pourquoi votre code est idiot, mauvais ou tout simplement faux.

Si vous avez lu jusqu'ici, lisez la documentation Hash pour l'initialisation.

Fondamentalement, un hachage initialisé avec plusieurs arguments les crée sous forme de paires clé / valeur:

Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}

Donc, dans votre exemple, cela conduirait au hachage suivant:

{"first_name"=>"mickey", "last_name"=>"mouse", "county"=>"usa"}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.