ruby中沒有嵌套的作用域,它的作用域之間是分開的,一旦進(jìn)入一個(gè)新作用域,原先的綁定就會(huì)被替換為一組新的綁定。
作用域門
一般來說,程序會(huì)在三個(gè)地方關(guān)閉前一個(gè)作用域,同時(shí)找開一個(gè)新的作用域。
它們分別是:class、module、def,它們被稱為作用域門。class/module與def還有一點(diǎn)微妙的差別。在類或module中的代碼會(huì)被立即執(zhí)行。相反,方法中的代碼只有在方法被調(diào)用的時(shí)候才執(zhí)行。
扁平化作用域
my_var = "abc"
class MyClass
def my_method
end
end
怎么樣在類MyClass中和方法my_method中使用my_var?
答案是這樣的類無法使用my_var,只能改變類和方法的定義方式。下面來做這件事情:
my_var = "abc"
MyClass = Class.new do
puts?my_var #這里可以使用了
define_method :my_method do
puts?my_var #這里可以使用了
end
end
共享作用域:
假設(shè)想在一組方法之間共享一個(gè)變量,這個(gè)變量又不想被別的方法訪問,就可以把這些方法定義在一個(gè)扁平作用域中:
def define_methods
shared = "abc"
Kernel.send :define_method, :my_method1 do
puts shared
end
Kernel.send :define_method, :my_method2 do
puts shared
end
end
instance_eval(): 打開接收者。
代碼塊
從底層看,使用塊需要分兩步:1、打包備用,2、調(diào)用塊(yield)來執(zhí)行代碼。
在ruby中絕大多數(shù)都是對(duì)象,但是塊不是。要存儲(chǔ)一個(gè)塊,你需要一個(gè)對(duì)象。Proc類可以做到。這個(gè)類提供了兩個(gè)內(nèi)核方法用于把塊轉(zhuǎn)化為對(duì)象:lambda()和proc(),還有兩種方法也能做到:Proc.new()和&操作符。
lambda()和proc()大多數(shù)情況下可以通用。但有些區(qū)別:
1、在lambda中return僅僅從這個(gè)lambda中返回,在proc中return是從定義proc的作用域中返回。
2、參數(shù)數(shù)量:lambda中如果參數(shù)數(shù)量不對(duì),會(huì)失敗,拋出一個(gè)ArgumentError的錯(cuò)誤。而proc會(huì)把傳來的參數(shù)調(diào)整為自己期望的參數(shù)形式。