2014-09-11 1 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 개의 인수를 취합니다. 세미콜론은 세미콜론 다음에 지정된 변수를 만들도록 루비에게 지시합니다.

예제에 이러한 규칙을 적용하면 두 예제의 블록 내부에서 세미콜론이 작동하는 방식을 테스트하기 위해 블록 외부에있는 변수에 할당해야한다는 것을 알아야합니다. 두 번째 예제는 그렇게하지 않습니다. 또한 두 번째 예제는 블록 매개 변수 변수 x를 지정합니다. 블록 매개 변수 변수는 항상 같은 이름을 가진 외부 변수를 숨 깁니다 (물론, 루비 1.8.7이 아님). 그래서 당신은 즉시 예제를 놓아 버렸습니다 : 블록 내에서 x에 대한 할당은 x 매개 변수 변수에 대한 할당이 될 것입니다 . (1.8.7- 루비 제외)

  1. 블록 매개 변수는 동일한 이름을 가진 외부 변수 숨겨 :

    두 가지만을 기억한다.

  2. '세미콜론 변수'는 동일한 이름의 외부 변수를 숨 깁니다.