檢視全域性和區域性變數

Kernel 公開了獲取 global_variableslocal_variables 列表的方法 :

cats  = 42
$demo = "in progress"
p global_variables.sort
#=> [:$!, :$", :$$, :$&, :$', :$*, :$+, :$,, :$-0, :$-F, :$-I, :$-K, :$-W, :$-a,
#=>  :$-d, :$-i, :$-l, :$-p, :$-v, :$-w, :$., :$/, :$0, :$1, :$2, :$3, :$4, :$5,
#=>  :$6, :$7, :$8, :$9, :$:, :$;, :$<, :$=, :$>, :$?, :$@, :$DEBUG, :$FILENAME,
#=>  :$KCODE, :$LOADED_FEATURES, :$LOAD_PATH, :$PROGRAM_NAME, :$SAFE, :$VERBOSE,
#=>  :$\, :$_, :$`, :$binding, :$demo, :$stderr, :$stdin, :$stdout, :$~]

p local_variables
#=> [:cats]

與例項變數不同,沒有專門用於獲取,設定或刪除全域性變數或區域性變數的方法。尋找這樣的功能通常表明應該重寫你的程式碼以使用 Hash 來儲存值。但是,如果必須按名稱修改全域性或區域性變數,則可以將 eval 與字串一起使用:

var = "$demo"
eval(var)           #=> "in progress"
eval("#{var} = 17")
p $demo             #=> 17

預設情況下,eval 將評估當前範圍內的變數。要評估不同範圍內的區域性變數,必須捕獲區域性變數所在的繫結

def local_variable_get(name, bound=nil)
  foo = :inside
  eval(name,bound)
end

def test_1
  foo = :outside
  p local_variable_get("foo")
end

def test_2
  foo = :outside
  p local_variable_get("foo",binding)
end
  
test_1 #=> :inside
test_2 #=> :outside

在上面,test_1 沒有通過對 local_variable_get 的繫結,因此 eval 在該方法的上下文中執行,其中名為 foo 的區域性變數被設定為:inside