Frage
params[:hello] # => "Some params value"
hello = params[:hello]
hello.gsub!("whatever","")
params[:hello] # => ""
Ich verstehe nicht, kann jemand bitte erklären, warum die params[:hello]
durch die gsub!
geändert werden? Ich erwartete die hello
Zeichenfolge geändert werden, aber nicht die params
Hash.
Lösung
hello
und params[:hello]
sind Verweise auf die gleiche Zeichenfolge. In Rubin (wie in Java und Python unter anderem) Zuordnung nicht den Wert kopieren, speichert er nur einen weiteren Verweis auf den gleichen Wert in den zugeordneten zu variabel. Also, wenn Sie die Zeichenfolge explizit kopieren, bevor es (mit dup
) Änderungen an der Schnur wirkt sich auf alle anderen Verweise auf die Zeichenfolge zu ändern.
Andere Tipps
Es gibt zwei Versionen von String#gsub
verfügbar
a= "abc" # => "abc"
b= a.gsub("b", "2") # "a2c"
a # => "abc"
c= a.gsub!("c", "3") # => "ab3"
a # => "ab3"
String#gsub!
modifiziert den ursprünglichen String und gibt einen Verweis darauf.
String#gsub
nicht das Original verändern und macht den Austausch auf einer Kopie.
Es ist ein verbreitetes Rubin Idiom zu nennen Methoden, die das Objekt mit einem !
ändern.
Wenn Sie nicht wollen, es zu modifizieren, müssen Sie es klonen, wie:
hello = params[:hello].clone
So wie du es jetzt tun, haben Sie einen Verweis darauf, keine Kopie.