2010-06-06 6 views
11

Ruby에서 블록이란 무엇을 의미합니까? Smalltalk와 유사하지만 메시지를 보낼 수는 없습니다. 스몰 토크에서 예를 들어Ruby에서 블록이 Smalltalk에 비해

:

[:x | x + 3] value: 3 

반환 6. 그러나 루비 :

{|x| x + 3}.call 3 

는 구문 에러가 발생합니다. , 블록, 블록 아닌 루비 그래서

irb(main):025:0> ->(x){x+3}.call 3 
=> 6 

을하지만 람다는 블록 :

글쎄, 당신은하지만, 루비에서 람다에게 메시지를 전달할 수 있습니다? 사실입니까? 루비 람다와 스몰 토크 블록 사이에 어떤 차이점이 있습니까? 이것이 사실이라면 루비 블록은 무엇입니까?

업데이트 : 함께 일부 인터넷 검색과

주석에서

아래 답변은, 내가 루비 블록의 더 이해가 같아요. 루비에서 보통 코드는 값을 평가하고 모든 값은 객체입니다. 그러나 블록은 값을 평가하지 않습니다. 그래서 그것은 대상이 아닙니다. 대신 부분의 개체로 작동 할 수 있습니다. 예를 들어, {| x | x + 3}는 객체 proc {| x | x + 3}.

하지만 혼란 스러웠습니다. 스몰 토크에서는 거의 모든 표현식을 객체로 나눌 수 있습니다 (변수에 대한 바인딩은 예외입니다). Ruby에서 더 많은 예외가있는 것으로 보입니다.

+0

나는 수익률이 부족하다고 생각합니다. 나는 블록에 대해 잘 알고 있지 않다. – Earlz

+0

yield를 지적 해 주셔서 감사합니다. 이 관련 질문을 찾았습니다 : http://stackoverflow.com/questions/764134/rubys-yield-feature-in-relation-to-computer-science – weakish

답변

14

루비 블록이 처음이자 가장 중요한 것은 객체가 아닙니다. 이것은 구문 구조이며 분명히 동등한 구현을 가지고 있지만 객체가 아니기 때문에 메시지를받을 수 없습니다. 귀하의 예가 다음과 같습니다.

{|x| x + 3}.call 3 

문법적이지 않습니다. Lambda, procs - 블록을 감싸는 객체이며 블록을 실행하는 메소드는 call입니다.

따라서 블록은 인수 목록 외부의 메서드로 전달 될 수있는 코드 조각 일 뿐이며 더 이상 필요하지 않습니다. 당신이 Proc.new 생성자에 전달하면, 예를 들어, 당신이 처리 할 수있는 그것을 포장하고 당신에게 객체를 줄 것이다 :

Proc.new {|x| x + 3}.call 3 
+0

Ruby 블록이 우리가 메서드에 전달하는 일부 객체라고 잘못 생각했습니다. 그것의 논증으로. 명확히 해 주셔서 감사합니다. – weakish

+0

그래서 올바르게 이해한다면 루비 블록을 매개 변수로 메서드에 전달할 때 VM이 어떻게 든 그것을 Proc.new로 래핑한다는 것을 의미합니까? – mathk

+0

나는 내부를 모릅니다. 그러나 당신이'&'표시로 그렇게하지 않으면 그것이 틀렸다는 것을 믿습니다. 암시 적 블록 (랩핑 없음) :'def yield3; 수율 3; 종료; yield3() {| x | puts x};'- 명시 적 proc (블럭이 전달되지 않음) :'def callprocwith3 (func); func.call (3); 종료; callprocwith3 (Proc.new {| x | puts x})'proc (블록을 ​​감싸기)로 변환 : def callblockwith3 (&func); func.call (3); end; callblockwith3() {| x | puts x};' - 모두 똑같은 일을하지만, 당신이 처리하는 방식이 다르다. 나는 빈 괄호'()'를 버릴 수 있었지만, 이런 식으로 논쟁이 무엇인지 명확하지 않다. – Amadan

1

정밀는 :

심지어 심지어 바인딩은 스몰 토크에서 그런 말 것 개체로 구성됩니다. MethodContext를 생각해보십시오. 실제로 수행하는 작업은 객체를 MethodContext에 저장하는 것입니다.

thisContext at: 1 put: Object new. 

을하지만 당신은 한 임시 직원 변수를 알 필요가 있기 때문에 분명히 당신은 늘 이런 식으로 쓰기 : 그래서

a := Object new 

은에서 재 작성 할 수 있습니다.

1

스몰 토크의 블록은 익명의 개체입니다. 구문 상, [ ... ] 쌍으로 구분됩니다.

평가할 때 평가 된 마지막 표현식이 반환되며 프로토콜에는 많은 메소드가 있습니다. 여기

는 (이 경우에, 돌고래 스몰 토크 6.03 커뮤니티 에디션) 스몰 토크에서 블록의 클래스 코멘트

는 "블록 나중에 수행 할 문장의 순서를 캡슐화한다. 블록 캡처 할 수 있습니다 (임시 변수의 값과 같은 런타임 상태가 생성되는 지점의 둘러싸는 어휘 범위에서 평가됩니다. 블록이 정의 된 어휘 범위 내에서 실행되는 것처럼 실행됩니다 (블록 제외). 블록은 평가시에 바인드 된 인수를 가질 수 있습니다. 블록은 메시지가 포함 된 인수와 함께 다른 객체에 전달 될 수 있으며 적절할 때 해당 객체에 의해 평가 될 수 있으므로 매우 강력하고 일반적인 "플러그 가능"메커니즘을 형성합니다 스몰 토크의 힘의 대부분을 제공하는 핵심 기능인 "

대조적으로 블록의 Ruby은 단순히 매개 변수 문자열입니다. 구문적으로는 { ... } 쌍으로 구분되지만 자체적 인 방법은 없습니다.

관련 문제