Ruby Language Décomposition


Exemple

Tout tableau peut être rapidement décomposé en affectant ses éléments à plusieurs variables. Un exemple simple:

arr = [1, 2, 3]
# ---
a = arr[0]
b = arr[1]
c = arr[2]
# --- or, the same
a, b, c = arr

Précédant une variable avec l'opérateur splat ( * ) y place un tableau de tous les éléments qui n'ont pas été capturés par d'autres variables. S'il n'en reste plus, un tableau vide est attribué. Une seule splat peut être utilisée dans une seule tâche:

a, *b = arr       # a = 1; b = [2, 3]
a, *b, c = arr    # a = 1; b = [2]; c = 3
a, b, c, *d = arr # a = 1; b = 2; c = 3; d = []
a, *b, *c = arr   # SyntaxError: unexpected *

La décomposition est sûre et ne génère jamais d'erreurs. nil s sont assignés là où il n'y a pas assez d'éléments, correspondant au comportement de l'opérateur [] lors de l'accès à un index hors limites:

arr[9000] # => nil
a, b, c, d = arr # a = 1; b = 2; c = 3; d = nil

La décomposition tente d'appeler implicitement to_ary sur l'objet affecté. En implémentant cette méthode dans votre type, vous avez la possibilité de la décomposer:

class Foo
  def to_ary
    [1, 2]
  end
end
a, b = Foo.new # a = 1; b = 2

Si l'objet décomposé ne répond pas respond_to? to_ary , il est traité comme un tableau à élément unique:

1.respond_to?(:to_ary) # => false
a, b = 1 # a = 1; b = nil

La décomposition peut également être imbriquée en utilisant une expression de décomposition délimitée par () à la place de ce qui serait sinon un seul élément:

arr = [1, [2, 3, 4], 5, 6]
a, (b, *c), *d = arr # a = 1; b = 2; c = [3, 4]; d = [5, 6]
#   ^^^^^

C'est effectivement l'opposé de splat .

En fait, toute expression de décomposition peut être délimitée par () . Mais pour le premier niveau, la décomposition est facultative.

a, b = [1, 2]
(a, b) = [1, 2] # the same thing

Bordure: un identifiant unique ne peut pas être utilisé comme motif de déstructuration, externe ou imbriqué:

(a) = [1] # SyntaxError
a, (b) = [1, [2]] # SyntaxError

Lors de l'affectation d' un littéral de tableau à une expression de déstructuration, external [] peut être omis:

a, b = [1, 2]
a, b =  1, 2  # exactly the same

Ceci est connu sous le nom d' affectation parallèle , mais il utilise la même décomposition sous le capot. Ceci est particulièrement pratique pour échanger des valeurs de variables sans employer de variables temporaires supplémentaires:

t = a; a = b; b = t # an obvious way
a, b = b, a         # an idiomatic way
(a, b) = [b, a]     # ...and how it works

Les valeurs sont capturées lors de la construction du côté droit de l'affectation. L'utilisation des mêmes variables comme source et destination est donc relativement sûre.