2016-12-29 20 views
15

Ben ruby ​​freeze yöntemini kullanıyorum. Donmanın tanımı dikkate alındığında, çağrıldığı nesnenin değerini dondurur. Bu nesnenin değerini sonra değiştiremeyiz. Aynı görevi başarmak zorunda, ben bir nesne var ve kod+ = operatör donmuş dizgiyi değiştirmek için görüntüleniyor

a = "Test" 
a.freeze 
a += "this string" 
puts a 

aşağıdaki gibi çıkışları verir şu yürütme ediyorum:

Test this string 
[Finished in 0.0s] 

benim donmuş dize değiştirme Neden?

+3

Olası kopyalar (http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby- çalışmıyor) – Manishh

+2

Değişkenler değişebilir; Bu yüzden değişken olarak adlandırılıyorlar. –

+1

Bunun bir yinelenen olduğunu görüyorum, ama bu iyi bir cevabı olan temiz bir sorudur, ki bu da beni bunun üzerinde çift çekiç kullanmaya isteksiz kılıyor. Daha büyük olmasına rağmen [aday gösterilmiş] (http://stackoverflow.com/questions/17067171/freezing-variables-in-ruby-doesnt-work) bu sorunun bir kopyası olarak işaretlemeyi tercih ederim. temiz değil. –

cevap

46

Hiçbir şey değiştiriyorsa senin dondurulmuş Sen

a = a + "this string" 

Eklemek olarak içten Ruby aynıdır

a += "this string" 

ile yeni String için a atanması yeniden edilir String

Ruby'de iki String nesnesi, sonucu içeren yeni bir String yaratacaktır (bu,için normal davranıştıroperatör bunu destekleyen çoğu nesnede). Bu orijinal "Test" ve "bu string" değerlerini değiştirmez. Orijinal, donmuş String ("Test" içeren), toplanana kadar hafızada kalır. Tüm referansları kaybettiğiniz için toplanabilir. Böyle bir yerde nesneyi değiştirmeye teşebbüs ederse

:

a << "this string" 

o zaman String nesneyle, Temel olarak, a şaşırtmamışımdır RuntimeError: can't modify frozen String

bir hata mesajı, yerel değişken görmelisiniz işaret ettiği Yerel değişkenler, Ruby tarafından depolanan nesnelerden bağımsız olarak herhangi bir zamanda yeniden atanabilir. Durumunuzda ne olduğunu doğrulamak için a.object_id numaralı telefonunuzu a += ... satırından önce ve sonra kontrol edebilirsiniz.

+4

Ayrıca not etmeye değer: 'a.object_id' önce ve sonra tamamen farklı. Bu şeyler, klonlanmış öğeler içeren bir dizi gibi garip bir şekilde davrandığında yararlı bir tanılamadır. – tadman

2

yöntemi, bir nesne değiştirmesini engeller dondurma, bir sabit bir nesne döner. Bu nedenle, bir nesneyi dondurduktan sonra, bunu değiştirme denemesi TypeError ile sonuçlanır.

s1 << "testing again" 

bu RuntimeError verecektir: değiştiremez dondurulmuş Dize

Ancak,

dondurularak bir değişken

s1 += "New Testing" 
puts "Object ID ===", s1.obejct_id 
üzerinde, bir nesne başvurusu çalışır

, yeni bir nesneye değerlendirileceğini ve nesne kimliğini de işaret edecek.Bu siteyi bakın Ayrıntılı bilgi için

, http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html

[çalışmıyor Ruby değişkenleri Donma] arasında