Que fait un opérateur double * (splat)


214

Avez-vous vu une fonction déclarée comme ça?

def foo a, **b
  ...
end

Je comprends qu'un seul *est l'opérateur splat. Que veut **dire?

Réponses:


373

Ruby 2.0 a introduit les arguments de mots clés et **agit comme *, mais pour les arguments de mots clés. Il renvoie un hachage avec des paires clé / valeur.

Pour ce code:

def foo(a, *b, **c)
  [a, b, c]
end

Voici une démo:

> foo 10
=> [10, [], {}]
> foo 10, 20, 30
=> [10, [20, 30], {}]
> foo 10, 20, 30, d: 40, e: 50
=> [10, [20, 30], {:d=>40, :e=>50}]
> foo 10, d: 40, e: 50
=> [10, [], {:d=>40, :e=>50}]

44
Cela répond parfaitement à la question, mais j'avais un petit addendum. Tout comme l'opérateur splat peut être utilisé sur le tableau que vous passez, le double splat peut être utilisé sur des hachages. Si opts = {d: 40, e: 50}, alors foo 10, opts, f: 60assignera {f: 60}à c, alors foo 10, **opts, f: 60assignera {d: 40, e: 50, f: 60}. Pour obtenir le deuxième effet, auparavant, vous auriez mergeexplicitement défini les tableaux.
brymck

Je suppose que cela est utile pour définir des paramètres de hachage facultatifs pour une méthode
bigpotato

Il vaut probablement la peine de noter que si vous mélangez des arguments de mot-clé avec un splat de mot-clé, le splat de mot-clé doit venir après les arguments de mot-clé.
MrMesees

43

C'est l' opérateur double splat qui est disponible depuis Ruby 2.0.

Il capture tous les arguments de mots clés (qui peuvent également être un simple hachage, ce qui était le moyen idiomatique d'émuler des arguments de mots clés avant qu'ils ne fassent partie du langage Ruby)

def my_method(**options)
  puts options.inspect
end

my_method(key: "value")

Le code ci-dessus s'imprime {key:value}sur la console.

Tout comme l'opérateur splat unique capture tous les arguments normaux, mais au lieu d'un tableau, vous obtenez un hachage .

Exemple concret:

Par exemple, dans Rails, la cycleméthode ressemble à ceci:

def cycle(first_value, *values)
  options = values.extract_options!
  # ...
end

Cette méthode peut être appelée comme ceci: cycle("red", "green", "blue", name: "colors").

C'est un modèle assez courant: vous acceptez une liste d'arguments et le dernier est un hachage d'options, qui peut être extrait - par exemple - à l'aide d'ActiveSupport extract_options!.

Dans Ruby 2.0, vous pouvez simplifier ces méthodes:

def cycle(first_value, *values, **options)
  # Same code as above without further changes!
end

Certes, ce n'est qu'une amélioration mineure si vous utilisez déjà ActiveSupport, mais pour Ruby ordinaire, le code gagne beaucoup de concision.


20

De plus, vous pouvez l'utiliser comme côté appelant comme ceci:

def foo(opts); p opts end
bar = {a:1, b:2}

foo(bar, c: 3)
=> ArgumentError: wrong number of arguments (given 2, expected 1)

foo(**bar, c: 3)
=> {:a=>1, :b=>2, :c=>3}

5
Wow, le double splat est analogue à l'opérateur de propagation d'objet d'ES6.
mpoisot

1
Merci, c'est la confirmation que je cherchais.
Qortex
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.