문제

def foo
  f = Proc.new { return "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo" 
end

def bar
  b = Proc.new { "return from bar from inside proc" }
  b.call # control leaves bar here
  return "return from bar" 
end

puts foo # prints "return from foo from inside proc" 
puts bar # prints "return from bar" 

나는 생각했다 return 키워드는 루비에서 선택 사항이며 항상 return요청 여부에 관계없이. 그 점을 감안할 때, 나는 그것이 놀랍습니다 foo 그리고 bar 사실에 의해 다른 출력을 결정합니다 foo 명시 적으로 포함됩니다 return 안에 Proc f.

왜 이것이 왜 그런지 아는 사람이 있습니까?

도움이 되었습니까?

해결책

루비에는 세 가지 구성이 있습니다.

  1. 차단하다 대상이 아니며에 의해 만들어집니다 { ... } 또는 do ... end.
  2. Proc a Proc 생성 된 개체 Proc.new 또는 proc.
  3. 람다 a Proc 만들어졌습니다 lambda (또는 proc 루비 1.8).

Ruby에는 세 가지 키워드가 있습니다.

  1. return 방법이나 람다가 종료됩니다.
  2. next 블록, Proc 또는 Lambda를 종료합니다.
  3. break 블록에 양보 된 방법을 종료하거나 Proc 또는 Lambda를 호출 한 방법을 종료합니다.

람다에서 return 처럼 행동합니다 next, 이유가 무엇이든지. next 그리고 break 그들이 다음과 같은 방법으로 가장 일반적으로 사용되기 때문에 그 방식으로 명명되었습니다. each, 블록을 종료하면 반복이 다음 컬렉션의 요소 및 종료 each 당신을 초래할 것입니다 부서지다 루프 밖으로.


사용하는 경우 return 정의 내부 foo, 당신은에서 돌아올 것입니다 foo, 블록이나 Proc 내부에 있더라도. 블록에서 돌아 오려면 next 대신 키워드.

def foo
  f = Proc.new { next "return from foo from inside proc" }
  f.call # control leaves foo here
  return "return from foo" 
end
puts foo # prints "return from foo"

다른 팁

이것은 의미론입니다 Proc에스; 반드시 모든 블록의 의미론은 아닙니다. 나는 이것이 약간 혼란 스럽다는 데 동의한다. 유연성이 추가 될 수 있습니다 (아마도 루비는 구현을 제외하고는 사양이 없을 것입니다).

동작은 다음에 정의됩니다 Proc 구현. LambdaS는 다르게 행동하므로 원한다면 return에스 종료하지 마십시오 둘러싸는 방법에서 사용하십시오 람다. 또는 생략하십시오 return 귀하의 키워드 Proc.

Rubys 폐쇄에 대한 깊은 조사 여기에. 환상적인 엑스포입니다.

그래서:

def foo   
  f = Proc.new {
    p2 = Proc.new { return "inner proc"};
    p2.call
    return "proc"
  }
  f.call
  return "foo"
end

def foo2
  result = Proc.new{"proc"}.call
  "foo2 (proc result is: #{result})"
end

def bar
  l = lambda { return "lambda" }
  result = l.call
  return "bar (lambda result is: #{result})"
end

puts foo
# inner proc
puts foo2
# foo (proc result is: proc) 
puts bar
# bar (lambda result is: lambda) 

이런 식으로 생각하십시오 : Proc.new 단지 호출 함수의 일부인 코드 블록을 만듭니다. Proc/Lambda는 특별한 바인딩이있는 익명 기능을 만듭니다. 작은 코드 예제가 도움이됩니다.

def foo
  f = Proc.new { return "return from foo from inside Proc.new" }
  f.call # control leaves foo here
  return "return from foo" 
end

동일합니다

def foo
  begin
    return "return from foo from inside begin/end" }
  end

  return "return from foo" 
end

따라서 반품이 'foo'함수에서 돌아올 것임이 분명합니다.

대조적으로 :

def foo
  f = proc { return "return from foo from inside proc" }
  f.call # control stasy in foo here
  return "return from foo" 
end

(이 예에서 사용되지 않으므로 바인딩을 무시하는 것과 같습니다) : :

def unonymous_proc
  return "return from foo from inside proc"
end

def foo
  unonymous_proc()
  return "return from foo" 
end

FOO에서 돌아 오지 않고 다음 진술로 계속 진행하지 않습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top