2013-11-21 2 views
2

지금 당장 나는 빈 문자열을 반환하는지에 따라 값을 변수로 설정하는 매우 추한 방법이라고 생각합니다. 아래는 문제의 방법입니다 (Nokogiri를 사용합니다. 그러나이 질문에는별로 중요하지 않습니다).Ruby 중첩 된 If 문

def get_let(response) 
    if response.css('A').empty? 
     if response.css('B').empty? 
      let = '' 
     end 
     let = response.css('B') 
    else 
     let = response.css('A') 
    end 

    return let 
end 
+0

무엇이 당신의 질문입니까? – sawa

답변

4
def get_let(response) 
    let = response.css('A') 
    let = response.css('B') if let.empty? 
    let = '' if let.empty? 
end 
2

제거 반환 및하자 :

def get_let(response) 
    if response.css('A').empty? 
     response.css('B').empty? ? '' : response.css('B') 
    else 
     response.css('A') 
    end 
end 

또는 컬렉션의 사용과

:

def get_let(response) 
    ['A', 'B'].map { |l| response.css(l) }.find { |items| !items.empty? } || '' 
end 

두 번 CSS 선택기를 계산 피한다.

+0

response.css ('A')와 response.css ('B')가 모두 비어 있으면'find'의 기본 인수는'NoMethodError : undefined method 'call "for" ": String'입니다. 'find '와 그것의 별칭'detect'는 1)이'nil'이거나 2)'call'에 응답한다는 인수를 필요로합니다. 콜렉션 접근법에 대한 대안 구현에 대한 내 대답을 참조하십시오. –

+0

좋은, 그것에 대해 잊어 버렸습니다. –

0

나는이 일을 아주 명쾌하게하고 있으며, 어떤 일이 벌어지고 있는지, 어떤 추론 로직을 가지고 있는지에 대해 추리하는 동안 그것을 추적 할 것입니다.

def get_let(response) 
    return '' if response.css('A').empty? && response.css('B').empty? 
    return response.css('B') if response.css('A').empty? 
    return response.css('A') if response.css('B').empty? 
end 
0

당신은 let 필요가 없습니다 - 그냥 ...

을가 ternaries보다 읽기 쉽게로 다음과 같이 유지하는 것을 선호 ...는 경우/다른 블록의 결과를 반환해야
def get_let(response) 
    if response.css('A').empty? 
    if response.css('B').empty? 
     '' 
    else 
     response.css('B') 
    end 
    else 
    response.css('A') 
    end 
end 
+0

이 접근법의 두 가지 단점은 여러 개의 리턴을 가지며 리턴은 내재적이라는 것입니다. 메소드에서 리턴 포인트가 여러 개인 경우'return' 키워드를 사용하여 명시 적으로 지정하는 것이 좋습니다. 나는'return'이 전형적으로 Rubyish가 아니라는 것을 알지만,이 코드를 사용하면 코드를 명확히 할 수 있기 때문에 예외를 만들 수 있습니다. –

0
def get_let(response) 
    case 
    when !response.css('A').empty? 
     response.css('A') 
    when response.css('A').empty? && !response.css('B').empty? 
     response.css('B') 
    else 
    '' 
    end 
end 
3

이것은 @ sethcall의 답변으로 확실히 읽을 수없는,하지만 당신은 몇 가지 루비 관용구 알고있는 경우가 꽤 읽을 수 있어야한다 :

을210

detect은 블록이 false를 반환하지 않는 첫 번째 결과를 반환합니다. 이것이 조건문을 피하는 이점이 있습니다. 위의 대답에 ||없이하고 싶은 경우에, 당신이 할 수 있습니다 :

def get_let(response) 
    responses = [response.css('A'), response.css('B')] 
    responses.detect(-> { '' }) { |response| !response.empty? } 
end 

그래도, 첫 번째 해결 방법으로 거의 직관적으로 그 두 번째 해결책을 찾을 수 없습니다. 빈 문자열을 인수로 지정할 수 있다면 좋을 것입니다. 그러나 detect 및 그 별칭 인 find에 대한 인수는 nil이거나 람다 또는 proc와 같은 call 메서드에 응답해야합니다. 기본 값이기 때문에 nil을 전달할 아무런 이유가 없습니다.

def get_let(response) 
    responses = [response.css('A'), response.css('B')] 
    responses.detect(&:any?) || '' 
end 

how detect works을에 대한 자세한 내용을 루비 문서를 참조하십시오 : 당신이 response.css 방법은 그것에 nil 또는 false 값으로 배열을 반환하지 않을 것을 확실히 알았다면

, 당신은이 솔루션을 시도 할 수 . 다음은 docs on any?입니다.

+1

레일즈 나 ActiveSupport를 사용하고 있다면'respond.detect (& : present) || '' –