2014-04-01 22 views
1

在JavaScript下面的習慣有時被用來容納範圍如何在Ruby中編寫內聯塊以包含局部變量作用域?

// JavaScript 
(function() { 
    var x = 0; 
    // do stuff 
})(); // execute anonymous function in-place 

// x is undefined (or its previous value) 

你瞧,這在Perl:

{ 
    local $/ = undef; 
    $file_contents = <FILE>; 
} 
# $/ == "\n" 

是否有紅寶石相似的地方?我能想出最接近的是:

Proc.new 
    x = 123 
    puts x 
end.call 
# x is undefined 

有另一種,在Ruby中要做到這一點比較常見的方式,或者這是它是如何做得最好?

+2

您提出的方法似乎是最簡單的解決方案。出於好奇,你的用途是什麼?在JavaScript中,我可以看到它有助於防止客戶端操縱全局變量,或者在包含各種腳本文件時防止與其他全局變量發生衝突,但這些在Ruby中沒有問題。 –

+0

用例不重要或永久。我對Ruby比較陌生,發現自己編寫臨時腳本來嘗試解決問題的幾種方法。在劇本中,我想在每次嘗試幾件事時保持每個「試驗塊」的範圍隔離。我最初嘗試了一個光禿禿的「do ... end」塊,這不起作用,有些令我驚訝。 – Steve

+1

我只會創建幾個方法,其中每個方法都會保留其本地變量。 –

回答

4

如果x塊前已經定義你的榜樣將無法工作:

x = 7 
Proc.new do 
    x = 123 
    puts x 
end.call 
# x is now 123 

紅寶石不會讓你與此相當晦澀的語法指定塊參數列表塊局部變量:

x = 7 
Proc.new do |;x| # declare x as block local 
    x = 123 
    puts x 
end.call 
# x is still 7 

;之後的任何變量都視爲該塊的局部變量,並且不會在封閉範圍中影響具有相似名稱的變量。

+0

這是關於現有變量的一個好處;謝謝,@matt。 – Steve

0

最近的解決辦法是使用stabby拉姆達符號:

-> { 
    x = 123 
    puts x 
}.call 

這不是在Ruby中很常見的這種情況下使用匿名特效。我能想到的最紅寶石的方式是將每個試驗放在小巧輕便的課堂中。

0

使用PROC

proc { 
    ... 
}[] 

已經相當小,雖然不是很習慣。你可以寫你自己的包裝,你可能會發現更優雅,因爲它避免了一個匿名函數創建

def wrap 
    yield 
end 

wrap do 
    ... 
end 

然而,正如@馬特指出,這並不妨礙你從塊的外部定義變量的訪問。