내가 더 잘 루비 폐쇄를 이해하려고 노력하고있어 나는 아주 이해하지 못하는이 예제 코드를 건너 온 :이해 루비 폐쇄
이def make_counter
n = 0
return Proc.new { n = n + 1 }
end
c = make_counter
puts c.call # => this outputs 1
puts c.call # => this outputs 2
누군가가 나에게 실제로 위의 코드 경우에 발생하는 이해하는 데 도움이 c = make_counter
으로 전화합니까? 내 생각에 다음과 같이 생각합니다.
Ruby는 make_counter
메서드를 호출하고 Proc와 연결된 코드 블록이 { n = 1 }
이 될 Proc 개체를 반환합니다. 첫 번째 c.call
이 실행되면 Proc 개체는 연결된 블록을 실행하고 n = 1
을 반환합니다. 그러나 두 번째 c.call
이 실행될 때 Proc 개체가 연결된 블록을 여전히 실행하지 않습니다 (여전히 { n = 1 }
입니까? 나는 출력이 2로 바뀔 이유를 알지 못한다.
어쩌면 나는 이것을 전혀 이해하지 못할 수도 있고, Ruby에서 실제로 일어나는 일에 대해 설명 할 수 있다면 도움이 될 것이다.
"... 먼저 발동 폐쇄 밖에서 선언 "정말 좋은 설명이 아닙니다. Proc 클로저 밖에서 Proc 내의 범위에없는 많은 장소가 있습니다. 그것은 Proc가 만들어 졌을 때'n'이 범위에 있었기 때문입니다. –
@AndrewMarshall, "Proc closure 외부"에 의해, 나는 단순히 범위 안에 있던'n '에 대한 파서의 첫 번째 발생이 Proc 내부에 있지 않다는 것을 의미했습니다. 확실히, 참조가 바인딩에 포함될 수있는 범위에 있어야합니다. - 이것이 확실하다고 가정 했었습니다 ... – PinnyM
죄송합니다.이 작업이 지루할 지 모르겠지만, 내 말로 당신이 말한 것을 설명하게하십시오. 이것이 올바른지 확인하십시오 : 정의에 따르면 코드 블록의 변수 n은 코드 블록 외부의 n에 바인딩됩니다. 이것이 의미하는 것은 Proc와 관련된 코드 블록이 c.call을 통해 평가 될 때 코드 블록은 n = n + 1 (1을 n으로 지정)을 실행하고 1을 반환한다는 것입니다. Proc와 관련된 블록이 실행될 때 두 번째로 다시 n = n + 1을 실행하지만 n은 1이므로이 블록은 2를 반환합니다. 올바르게 설명하겠습니까? – wmock