La différence dans votre code n'est pas sur <<
par rapport à push
, c'est sur le fait que vous réaffectez dans un cas et pas dans l'autre. Voici deux morceaux de code sont équivalentes:
@connections = Hash.new []
@connections[1] = @connections[1].push(2)
puts @connections # => {1=>[2]}
@connections = Hash.new []
@connections[1] = (@connections[1] << 2)
puts @connections # => {1=>[2]}
Comme sont ces deux:
@connections = Hash.new []
@connections[1].push(2)
puts @connections # => {}
@connections = Hash.new []
@connections[1] << 2
puts @connections # => {}
La raison pour laquelle Réaffectation fait une différence ici est que l'accès à une valeur par défaut, ne pas ajouter automatiquement une entrée pour le hash. C'est si vous avez h = Hash.new(0)
et puis vous faites p h[0]
, vous imprimerez 0, mais la valeur de h
sera toujours {}
(pas {0 => 0}
) parce que le 0 n'est pas ajouté au hachage. Si vous faites h[0] += 1
, cela appellera la méthode []=
sur le hachage et ajoutera effectivement une entrée pour 0, h
devient {0 => 1}
.
Alors, quand vous faites @connections[1] << 2
dans votre code, vous obtenez le tableau par défaut et effectuer <<
là-dessus, mais vous ne stockons rien dans @connections
, il reste {}
. Lorsque vous faites @connections[i] = @connections[i].push(2)
ou @connections[i] = (@connections[i] << 2)
, vous appelez []=
, de sorte que l'entrée est ajoutée au hachage.
Cependant, vous devez noter que le hachage renvoie une référence au même tableau à chaque fois, même si vous ajoutez l'entrée du hachage, il sera probablement toujours pas se comporter comme prévu une fois que vous ajoutez plus d'une entrée (puisque toutes les entrées se réfèrent au même tableau):
@connections = Hash.new []
@connections[1] = @connections[1].push(2)
@connections[2] = @connections[2].push(42)
puts @connections # => {1 => [2, 42], 2 => [2, 42]}
Qu'est-ce que vous voulez vraiment est un hachage qui renvoie une référence à un nouveau tableau chaque fois qu'une nouvelle clé est accessible et qui ajoute automatiquement une entrée pour le nouveau tableau quand cela arrive. Pour ce faire, vous pouvez utiliser le formulaire de bloc de Hash.new
comme ceci:
@connections = Hash.new do |h, k|
h[k] = []
end
@connections[1].push(2)
@connections[2].push(42)
puts @connections # => {1 => [2], 2 => [42]}
Malheureusement, cela ne répond pas à ma question. Le fait que push accepte plus d'un argument n'explique pas le comportement ci-dessus. – Sergey
Dans votre premier exemple de code, vous n'avez pas simplement remplacé push() par << avez-vous? Vous avez peut-être aussi essayé ce qui suit dans votre deuxième exemple: '@connections [1] .push (2)' et ensuite demandé: "Quelle est la différence entre push() et push()?" – 7stud