2013-05-18 55 views
1

有人可以解釋我,爲什麼我的原始常量LIST從一開始就被操縱在最後?我認爲常量可能只是一次初始化。我想將操作存儲在新陣列中(new_list),而不影響原始操作(LIST)。奇怪的紅寶石行爲與恆定

$ned = "foo" 
$med = "" 

print LIST = [:nrd, :mrd_y] # -> [:nrd, :mrd_y] 


list = LIST 

new_list = list.delete_if { |element| 
    case element 
    when :nrd then $ned.empty? 
    when :mrd_y then $ned.empty? || $med.empty? 
    end 
} 

print new_list # -> [:nrd] 

print LIST # -> [:nrd] instead of [:nrd, :mrd_y] 

回答

2

Array#delete_if - >刪除自的每個元素爲哪個塊評估爲真。

$ned = "foo" 
$med = "" 

LIST = [:nrd, :mrd_y] 
p LIST.object_id #=> 84053120 
list = LIST 
p LIST.object_id #=> 84053120 
new_list = list.delete_if { |element| 
    case element 
    when :nrd then $ned.empty? 
    when :mrd_y then $ned.empty? || $med.empty? 
    end 
} 

Listlist保持相同Array對象,如上述object_id講述。因此,對於來自塊delete_if的每個true評估,刪除84053120引用的對象中的項目。它由LISTlist保存。所以你可以用下面的:

$ned = "foo" 
$med = "" 

LIST = [:nrd, :mrd_y] 
list = LIST 
new_list = list.dup.delete_if { |element| 
    case element 
    when :nrd then $ned.empty? 
    when :mrd_y then $ned.empty? || $med.empty? 
    end 
} 

p new_list #=>[:nrd] 
p LIST #=>[:nrd, :mrd_y] 

或(更好的方法使用Array#reject),

$ned = "foo" 
$med = "" 

list = [:nrd, :mrd_y] 
new_list = list.reject { |element| 
    case element 
    when :nrd then $ned.empty? 
    when :mrd_y then $ned.empty? || $med.empty? 
    end 
} 
p new_list #=>[:nrd] 
p list #=>[:nrd, :mrd_y] 
+0

你也可以使用['reject'(HTTP://紅寶石文檔。 org/core-2.0/Array.html#method-i-reject),如果這使得塊的邏輯更清晰。我認爲'select'或'reject'方法是我期望在Ruby代碼中看到的。 –

+0

@ muistooshort你是對的!我有一段時間忘了「拒絕」。感謝指針。現在更新。 –

+0

感謝您的建議。在這兩種情況下,我不需要中間步驟'list = LIST'了,正確的(只是'LIST.reject')? – ericMTR