2014-09-11 36 views
0

一本書指出,即使在程序中其他位置存在具有相同名稱的其他變量,也可以將其範圍限制爲塊的變量。你可以在垂直管道內的塊變量之前使用;僅限塊的示例塊參數

,但我得到了相同的結果與不低於塊變量x

def block_local_variable 
    x = "Original x!" 
    3.times do |i;x| 
     x = i 
     puts "x in the block is now #{x}" 
    end 
    puts "x after the block ended is #{x}" 
end 
block_local_variable 

def block_local_variable 
    x = "Original x!" 
    3.times do |x| 
     puts "x in the block is now #{x}" 
    end 
    puts "x after the block ended is #{x}" 
end 
block_local_variable 

據我所看到的,沒有區別。

x in the block is now 0 
x in the block is now 1 
x in the block is now 2 
x after the block ended is Original x! 

原始x仍然不受保護。

我錯了嗎?這個特定的代碼片段可以有相同的結果,但從更廣泛的角度來看,東西真的不同,對吧?

回答

1

這裏有一個更簡單的方法來解釋你的書想告訴你什麼。

1)塊可以看到周圍範圍內的所有變量 - 在創建塊時。這裏有一個例子:

y = 'hello world' #<-+ <--- Everything outside the block is part of the surrounding scope 
        # | 
func = lambda do #<-|---- Block created now! 
    puts y #---------+ 
end 

func.call #=>hello world 

以下是沒有必要知道你的問題,但它是很好的在任何情況下,要知道:一個塊不能看到周圍的範圍中的變量 - 在當時被執行。下面是一個例子:)內的塊

y = 'hello world'# <-+ 
       # | 
func = lambda do # <-|------Block created now! 
    puts y #----------+ 
end 

def do_stuff(f) #<--- The def keyword creates a new scope. 
#----------------------+ <-- The scope surrounding the block. 
    y = 10 #   | 
    f.call #=>puts y <---Block executed now! 
#----------------------+ 
end 

do_stuff(func) #=>hello world 

2,你可以改變的變量在周邊範圍:

y = 'hello world'# <-----+ 
       #  | 
func = lambda do #  | 
    y = 'goodbye' #-------+ 
end 

func.call 
puts y #=>goodbye 

3)現在,如果你想使用一個名爲變量「 y',但是你不想在已經命名爲'y'的塊之外改變一個變量?換句話說,您不希望搜索所有代碼,以查看是否已有一個名爲'y'的變量可能會無意中更改,這可能會導致錯誤?

y = 'hello world' 

func = lambda do |;y| #New y variable created, which 'hides' the outer y. 
    y = 'goodbye'  #Assignment to the 'local' (or block) y. 
end #Block y is destroyed--'unhiding' the outer y. 

func.call 
puts y #=>hello world 

請注意,分號後列出的變量不是參數變量 - func需要0個參數。分號只是告訴ruby創建在分號後指定的變量。

如果您將這些規則應用於您的示例,您應該認識到爲了測試分號如何工作,在兩個示例的塊內必須分配給塊外部存在的變量。你的第二個例子不這樣做。另外,你的第二個例子指定了一個塊參數變量x。一個塊參數變量ALWAYS隱藏一個外部變量具有相同的名稱(當然,不是在ruby 1.8.7中),所以你立即通過這樣做來阻止這個例子:在塊內部,對x的賦值將是對x參數變量的賦值。

只要記住兩件事情:

  1. A嵌段參數變量隱藏具有相同名稱的外可變(除了在紅寶石1.8.7-)。

  2. '分號變量'隱藏一個具有相同名稱的外部變量。