2014-06-20 1 views
0

나는 명시적인 반환과 암시 적 반환 사이의 차이점을 조사하기 위해 자체 정의 include? 메서드를 사용하고 있습니다. 나는 #each이 반복 된 컬렉션을 반환한다는 것을 이해하고 있으므로 올바른/잘못된 암시 적 반환 값을 올바른 위치에 배치해야한다고 생각합니다. 그러나 컬렉션을 다시 가져올 때 무엇을 수정해야할지 모르겠습니다.Ruby의 암시 적 반환 값 범위

def self.include?(array, search_item) 
    array.each do |elem| 
    if elem == search_item 
     true 
    end 
    end 
end 

다음은 내가 테스트하고있는 테스트입니다. 그러나 리턴 값을 정확하게 일치시키는 방법을 모르겠습니다. 일치하지 않는 이유는 무엇입니까? 또는 내재 된 수익의 범위를 어떻게 이해해야합니까?

result = MethodReturns.include?(numbers_array, 4) 
    expect(result).to eq(true) 

    result = MethodReturns.include?(numbers_array, 7) 
    expect(result).to eq(false) 

답변

3

당신은 변경하기를 원할 것입니다 : 방법의 마지막 문이 반환 값 때문에

def self.include?(array, search_item) 
    array.each do |elem| 
    if elem == search_item 
     return true 
    end 
    end 
    return false 
end 

그 이유는. 귀하의 경우에는 일치가 없을 경우 false를 반환하지 않습니다. 중단하여 나머지 메소드 실행을 즉시 중지하려면 return을 추가해야합니다.

+3

코드는 정확하지만 설명이 없습니다. 'return' _inside_ 루프가 중요합니다. 그렇지 않으면'true'가'each'에 의해 삼켜지고 반환되지 않을 것입니다. – Max

+0

기본적으로 실행 방법을 벗어날 필요가있을 때마다 항상 회신을 작성하므로 절대로 그렇게 생각하지 않습니다. 추가 해줘서 고마워. – Tacoman667

+1

@Max 추가 설명 : 블록에 의해 반환되는 값은 블록에서 실행되는 마지막 식입니다. 'each' 메쏘드는 블록을 취하는데이 경우 블록은 현재 요소가 검색 항목이라면 참을 반환하고, 그렇지 않으면 거짓을 반환합니다. 그러나이 문제는'each' 메쏘드가 블록의 각 실행으로부터의 출력을 무시하고 대신에 각 메쏘드가 호출 된 배열을 반환하도록 정의됩니다. 그래서,'each' 메소드 호출이 메소드의 마지막 표현 이었기 때문에, 배열은이 구현물에 의해 리턴됩니까? – Max

2

실행 된 LAST 문은 반환 값을 제공합니다. 각() 루프에서 일어나는 마지막 것은 항상 루프의 끝 될 것입니다 (어떻게 든 루프의 탈옥하지 않는 한, 예를 들어, 반환, 휴식) :

def do_stuff() 
    [1, 2, 3]. each do |num| 
    true if num == num 
    end 
end 

p do_stuff 

--output:-- 
[1, 2, 3] 

그래서 당신의 진정한 값을 멀리 던져 도착, each() 루프가 끝날 때까지 each() 반복은 계속됩니다. 아시다시피 each() 루프가 끝나면 왼쪽이 반환됩니다. 여기

이 암시 적으로 true를 반환하는 방법의 예 :

def do_stuff() 
    [1, 2, 3]. each do |num| 
    #blah 
    end 

    true 
end 

다음은 각() 메소드는 여전히 배열 반환 -하지만를 각() 메소드가 do_stuff에서 실행하는 마지막 문이 아닌 () 방법. 당신의 예에서

, 당신은 이 작업을 수행 할 수 있습니다 :

def do_stuff(target) 
    found = false 

    [1, 2, 3]. each do |num| 
    found = true if num == target 
    end 

    found 
end 


p do_stuff(2) 

--output:-- 
true 

그러나, 솔루션 자원을 낭비 일치하는 항목이 발견 된 후 각() 메소드는 배열의 반복을 계속하기 때문이다. 예를 들어, 배열에 100 만 개의 요소가 있고 Array의 인덱스 0에서 일치하는 항목이 발견되면 each() 메서드는 불필요하게 나머지 999,999 개 요소를 반복하여 반복합니다. 반면에 일치가 발견되면 명시 적으로 반환하면 루프가 종료됩니다.

명시 적으로 return val을 쓰는 것은 결코 실수가 아닙니다. 더 많은 경험을 쌓으면 리턴 부분을 버릴 수 있습니다 - 때론 적당합니다 - 당신이 루비를 아는 세계를 보여줄 수 있습니다 ... 그러나 지금은 언제든지 return을 생략하면 당신을 계속 여행 할 것입니다.

2

each 블록 내에 명시적인 return을 사용하는 경우 해당 코드에 도달하면 즉시 값이 반환됩니다 (반복 중지).

루비 블록

지원 비 로컬 복귀하는 복귀 에서 블록이 블록의 원래 문맥에서 반환 동일하게 작동한다는 것을 의미 : 이는 블록 non local return 기능이다.

그래서 당신은 단순히 명시 적 return를 사용하는 경우 코드가 제대로 작동해야합니다

def self.include?(array, search_item) 
    array.each do |elem| 
    if elem == search_item 
     return true 
    end 
    end 
end