2016-07-14 9 views
0

Programm erklären:Verwenden von string.next zum Zuweisen von Hashwerten innerhalb einer Schleife. Ich kann nicht die folgende Ausgabe

letter = "a" 
chars = Hash.new 

for i in 1..5 
    chars[i] = letter 
    puts letter 
    letter.next! 
end 

puts chars 

=== Ausgang:

a 

b 

c 

d 

e 

{1=>"f", 2=>"f", 3=>"f", 4=>"f", 5=>"f"} 

=== Frage

Ich verstehe nicht, warum ich nicht bekommen, {1=>"a" , 2=>"b" , 3=>"c", 4=>"d" , 5=>"e" }

Ich habe die Puts-Anweisung eingefügt, um zu überprüfen, dass der Buchstabe in jeder Phase der Iteration korrekt ist.

Vielen Dank im Voraus.

+0

Hinweis: Wie viele verschiedene Strings haben Sie in Ihrem Code erstellt? –

Antwort

4

chars[i] = letter weist keine letter zu chars[i] zu. letter ist eine Referenz auf die Zeichenfolge "a" und weist diese Referenz auf chars[i] zu. Also, nachdem Sie char[1] = letter zuweisen, dann ändern Sie letter mit letter.next!, char[1] verweist jetzt auf den gleichen, neuen Wert der Zeichenfolge, die letter tut. Siehe Ruby: how can I copy a variable without pointing to the same object?, und ändern Sie Ihren Code:

for i in 1..5 
    chars[i] = letter.dup # Assign a copy of `letter` to chars[i] 
    puts letter 
    letter.next! 
end 
1

Das Ausrufezeichen in letter.next! gibt es potenzielle Gefahren hin: next! ändert die ursprüngliche Zeichenfolge. Alle Werte im Hash sind die gleiche Zeichenfolge und werden jedes Mal geändert.

(Fast?) Immer gibt es eine Nicht-Ausrufezeichen-Version der Methode - die "sichere" Version. In diesem Fall ändert es nicht die ursprüngliche Zeichenfolge, es liefert eine neue Zeichenfolge.

letter = "a" 
chars = Hash.new 

for i in 1..5 
    chars[i] = letter 
    puts letter 
    letter = letter.next # new string !! 
end 

puts chars # => {1=>"a", 2=>"b", 3=>"c", 4=>"d", 5=>"e"}