2013-10-09 68 views
0

我有一段代碼存在問題。具有相同對象ID的Ruby變量

temp_state = @state 

我想要做的就是我的實例變量@state的值賦給新的局部變量temp_state。問題是,當我做

temp_state.object_id = 70063255838500 
state.object_id = 70063255838500 

當我修改temp_state我也修改@狀態。如何在不修改@state的內容的情況下使用temp_state?

這裏有階級的重要組成部分:

class SearchNode 
    attr_accessor :state, :g, :f, :free_index 

    def initialize(state, parent = self) 
    @state = state 
    @g = parent == self ? 1 : parent.g 
    @h = calculate_h 
    @f = @g + @h 
    @valid_action = ["Move(Black)", "Move(Red)", "Jump(Black)", "Jump(Red)"] 
    @free_index = index_of_free 
    @parent = parent 
    end 

    def move_black_jump 
    free = @free_index 
    # PROBLEM NEXT LINE 
    temp_state = @state 
    if temp_state[free + 2] == 'B' || temp_state[free - 2] == 'B' 
     if free - 2 >= 0 && free + 2 <= temp_state.length 
     index = free - 2 if temp_state[free - 2] == 'B' 
     index = free + 2 if temp_state[free + 2] == 'B' 
     else 
     puts "ERROR: Movement out of bounds." 
     end 
     x = temp_state[index] 
     temp_state[index] = 'F' 
     temp_state[free] = x 
    else 
     puts "ERROR: Wrong movement move_black_jump." 
    end 
    return temp_state 
    end 

end 

謝謝您的幫助。

+0

至少有兩個答案指出'dup'使接收器的'淺'副本。如果您或其他讀者不瞭解限定詞「淺」的意義,這兩個示例可能會有所幫助:'a = [1,2,3]; b = a.dup#=> [1,2,3]; a [1] ='cat'#a => [1,「cat」,3],b => [1,2,3]'但如果'a = [1,[2,3]]; b = a.dup#=> [1,[2,3]];一個[0] = '狗'; a [1] ='貓'#a => [「狗」,[2,「貓」],b => [1,[2,「貓」]]。 –

回答

3

您必須複製對象,而不是將新變量引用傳遞給同一對象。你讓(淺)複製與Object#dup方法:

temp_state = @state.dup 
+0

Ruby中存在顯式指針?我一直認爲他們只是參考他們的價值觀 – Edmund

1

當您指定的紅寶石變量到另一個變量是指向第一,你在這裏找到了。在Ruby中有很多方法可以解決這個問題。一個是.dup方法,它使第一個變量的淺拷貝而不僅僅是一個引用。看看他在這裏的文檔:http://ruby-doc.org/core-2.0.0/Object.html#method-i-dup

1

你想temp_state = @state.dup但這不適用於所有的對象,即。 Fixnums。