2010-11-21 4 views
1

저는 최근에 쓰지 않은 Ruby 메서드를 단순화하기 위해 노력했습니다. 동료가 작성한 기존 프로젝트의 일부입니다. 일반적으로 우리는 코드 채무가 누적되지 않는 훌륭한 일을 해 냈습니다. 그러나 약간의 사랑이 필요한 몇 가지 방법이 있습니다.Ruby-ish 방식으로이 방법을 단순화하는 방법은 무엇입니까?

단순화 한 방법은 원래 중첩 된 if-else 블록의 대량이었습니다. 메소드가 무엇을하는지 결정하고 메소드를 단순화하여 더 이상 중첩 된 if가 없도록했습니다.

이제 더 단순화하고 가능한 경우 하나의 return 문을 제외한 모든 것을 제거하고 싶습니다. 이 방법은 더 이상이보다 있지만, 그것이 지금의 모습의 일반적인 개념이다 : 나는 return 문을 줄이기 위해 raise 및 예외 처리를 사용하는 방법에 대한 생각

def return_bool 
    return false unless condition1 && condition2 
    @var = SomeClass.getter(foo) 
    return true unless var.someProperty != 0 
    @stuff = @var.getsomething id 
    return false unless @stuff && somethingElse 
    data = JSON.parse(@stuff) 
    @stuff.each do |stuff| 
    return false if data[stuff['something']] != stuff['anotherSomething'] 
    end 
    return true 
end 

하지만 경우, 예를 들어, condition1이 거짓 , 그것은 예외적 인 상황이 아니며, 나는 특정 시간에 그것을 기대한다.

return 문을 줄이는 방법은 무엇입니까? 가능하다면 실제로 가능하면 암묵적으로 반환하는 것을 선호합니다. 대신 마지막 .each 루프의

+0

는'raise'는'실제로 유용한 무언가를 – Nakilon

+0

을 return'보다 결코 더 나은 무엇입니까? –

+0

@ 그렉 예. 앞서 언급했듯이, 더 큰 방법이지만 작은 코드 샘플을 게시하여 요지를 얻고 싶습니다. – Alex

답변

0

샘플 코드는 Ruby가 해당 메소드 정의 실행을 거부하기 때문에 작동하지 않습니다.

이것은 어떻게 풀릴 지 알려주지 만 로컬 변수 나 샘플 값이 없으면 SomeClass의 정의를 테스트 할 방법이 없습니다.

def return_bool 
    if (condition1 && condition2) 
    @var = SomeClass.getter(foo) 
    if (var.someProperty == 0) 
     @stuff = @var.getsomething id 
     if (! (@stuff && somethingElse)) 
     data = JSON.parse(@stuff) 
     @stuff.each do |stuff| 
      return false if data[stuff['something']] != stuff['anotherSomething'] 
     end 
     end 
    end 
    end 
    return true 
end 
+0

이것은 나에게 약간의 아이디어를 제공한다. 감사! +1하고 받아들입니다. – Alex

+0

원본 코드에서 본 # 1 건은 '제외'에 대한 무시 무시한 신뢰입니다. 그것은 if (! some_boolean_value)와 동일하지만, 우리의 뇌가 초과 근무시에 무슨 일이 일어나고 있는지를 해독합니다. 'unless'를 사용하여'if (! ...) '문을 변경함으로써'if' 문이 같은 논리에 가까울 것으로 보입니다. –

+0

@theTinMan 나는 아주 늦었다 고 알고 있지만 원래 코드는'condition1 && condition2'가'false' 일 때'false'를 리턴하고 코드는'true'를 리턴합니다. – michau

1

사용 .all? : 그런데

def return_bool 
    return false unless condition1 && condition2 
    @var = SomeClass.getter foo 
    return true unless var.someProperty != 0 
    @stuff = @var.getsomething id 
    return false unless somethingElse && @stuff 
    data = JSON.parse @stuff 
    @stuff.all? do |stuff| 
    data[stuff['something']] == stuff['anotherSomething'] 
    end 
end 

,이 holywar처럼 IFS 대 돌아갑니다. 나는 반환을 선호한다.
또한 반품을 원하지 않으실 경우에는 어떻게해야합니까?

def return_bool 
    condition1 && condition2 && (
    @var = SomeClass.getter foo 
    var.someProperty.zero? || (
     (@stuff = @var.getsomething id) && somethingElse && (
     data = JSON.parse @stuff 
     @stuff.all? do |stuff| 
      data[stuff['something']] == stuff['anotherSomething'] 
     end))) 
end 
+0

이것에 대해서는 약간 생각해 봐야 겠지만'somethingElse'가 위선 인 경우'@stuff = ...'는 평가되지 않습니다. 원래 버전에서는 할당이 수행됩니다. –

+0

BTW : 이중 부정은 조금 불쾌 해 보입니다. var.someProperty.zero 인 경우 true를 반환합니다. –

+0

@ Jörg W Mittag, 두 의견 모두에 동의합니다. 나는 다시 써야한다 ... – Nakilon

2

ExtractMethod를 사용하여 메서드를 더 작은 논리 부분으로 잘라냅니다. 테스트 결과 아무 것도 깨뜨리지 않도록 도움을 줄 것입니다. http://www.refactoring.com/catalog/extractMethod.html

def return_bool 
    some_condition? && 
     var_is_valid? && 
     stuff_is_valid? && 
     parsed_stuff_has_something? 
    end 

    def get_var 
    @var = SomeClass.getter(foo) 
    end 

    def get_stuff 
    @stuff = @var.getsomething id 
    end 

    def some_condition? 
    condition1 && condition2 
    end 

    def var_is_valid? 
    get_var.someProperty == 0 
    end 

    def stuff_is_valid? 
    get_stuff && somethingElse 
    end 

    def parsed_stuff_has_something? 
    data = JSON.parse(@stuff) 
    @stuff.each do |stuff| 
     return false if data[stuff['something']] != stuff['anotherSomething'] 
    end 
    true 
    end 
관련 문제