[英]Ruby - Clear all the global variables
我正在使用現有的框架進行並行執行。 這里使用了很多全局變量。 我可以看到一些全局變量(是的,我們應該避免它,但在這種情況下,我沒有選擇)正在產生問題。 global_variables顯示所有使用的全局變量的列表。 我想在每次執行結束時清除它們。 請問有什么建議嗎? ((
您不想清除所有全局變量,因為 Ruby 依賴於許多全局變量和常量才能正常運行。 不過,可以清除您定義的那些。
但是,您實際上不能取消定義全局變量,盡管您當然可以重新分配它們的值。 重構命名空間或詞法范圍的變量應該是一個長期目標,即使下面的建議現在對你有用。 傳遞綁定、值、配置設置和不依賴全局變量的對象引用有很多選項,在大多數情況下,減小變量范圍通常是正確的做法。
也就是說,這里有一些建議可能對您的情況有所幫助。 我還注意到一些邊緣情況可能適用於您的代碼,也可能不適用於您的代碼,但在處理頂級綁定和全局命名空間時,這些情況應該放在您的腦海中。
根據定義,全局變量永遠不會超出范圍。 這也意味着變量本身也永遠不能被垃圾收集。
此外,與實例變量類似,但與類或局部變量不同,全局變量在引用時自動激活*為nil
,以防止出現 NameError。 即使你從未真正定義過$foo , $foo == nil #=> true
。
*作為一個微妙的區別, defined? $foo #=> nil
defined? $foo #=> nil
而$foo = nil; defined? $foo #=> "global-variable"
$foo = nil; defined? $foo #=> "global-variable"
$foo = nil; defined? $foo #=> "global-variable"
,但我認為這對您的問題沒有任何實際影響。
如果您的主要目標只是“取消設置”全局變量的值,您可以執行以下操作:
NILABLE_GLOBALS = %w[$foo $bar $baz]
NILABLE_GLOBALS.map { eval "#{_1} = nil" }
雖然變量在技術上仍然是定義的,但實際上它們會以類似的方式響應未定義,例如等於nil
。
這種方法還可以通過將全局變量全部指向一個單例對象(例如 NilClass 的唯一實例)來最小化全局變量的內存占用。 如果以前存儲在全局變量中的值在不再引用它們時被垃圾收集,這應該會減少內存使用量。 可能有幾個邊緣情況,比如存儲在 TOPLEVEL_BINDING 中的凍結字符串,我不確定這些值是否真的會丟失所有引用並因此被垃圾收集,但這更多的是內存管理問題而不是值分配或對象身份問題,如果內存是主要問題,那么您一開始就不會使用全局變量。
只要你不依賴defined?
重置值時返回nil
,這似乎是您最好的選擇,而不是重構代碼以使用可能超出范圍的變量。
如果您使用的是無法垃圾收集符號的舊版 Ruby,請盡可能將 String 對象分配給您的全局變量。 如果您發現即使不再引用它們也沒有被垃圾收集,您也可以默認禁用凍結字符串。 如果內存過度膨脹,您可以在調用GC 模塊后檢查ObjectSpace以查找不需要的 Symbol 和 String 對象。 雖然這些對你來說不太可能是真正的問題,但如果是的話,至少你有一個起點。
在您的程序的某個早期階段,記錄 Ruby 解釋器本身提供的全局變量並將其存儲在一個常量中:
OrigGlobalVars = global_variables
我認為沒有辦法取消定義全局變量,但您可以通過執行以下操作將代碼創建的所有新變量設置為nil
:
(global_variables - OrigGlobalVars).each { |g| eval "#{g} = nil" }
這肯定會破壞一些使用全局變量的代碼,因為代碼可能沒有被設計為優雅地處理變量為 nil 的情況。 但是你可以在它們出現時修復它們。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.