ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Programming Ruby (20) 예외처리 - 2
    Ruby 2016. 11. 5. 11:38
    [출처] Programming Ruby 
    (본 게시물은 저작권의 문제 발생시 출판사의 요청에 의해 삭제될 수 있습니다.)



    Catch와 Throw 


    raise와 rescue 메커니즘은 무언가 잘못되었을 때 실행을 멈추는데 효과적이다. 일반적인 실행 중에 여러 겹으로 둘러싸인 코드 밖으로 탈출할 수 있다면 유용할것이다. 이 때 사용하는 문법이 catch throw 이다. 


    아래의 예제는 한 번에 하나씩 단어 리스트를 읽어와 배열에 추가한다. 전부 읽어오고 나서 배열을 역순으로 출력한다. 처리 과정에서 정상적인 단어를 포함하지 않는 줄을 만나면 모든 과정을 중지한다.


    word_list - File.open("wordlist")

    catch (:done) do

         result =  [  ]

         while line = word_list.gets

              word = line.chomp

              throw :done unless word =~ /^\w+$/

              result << word 

         end

         puts result.reverse

    end


    catch는 이름(Symbol, String)이 붙여진 블록을 정의한다. 이 블록은 throw를 만날 때까지 실행된다. throw를 만나면 루비는 해당하는 심벌을 가진 catch를 찾아 코드를 거슬러 올라간다. 그리고 찾게 되면 루비는 해당 위치로 되돌린 뒤 블록을 종료한다. 


    따라서 위의 예제는 입력된 문자열이 정상적인 형식을 가지지 않았을 경우 throw에 대응하는 catch 블록의 끝으로 이동한다. while을 반복하는 것 뿐만 아니라 거꾸로 리스트를 출력하는 출력도 실행하지 않는다. throw에 두 번째 매개 변수를 넘겨주면 그 값이 catch의 반환값이 된다. 


    아래의 예제에서는  "wow*."라는 잘못된 줄이 포함되어 있어 블록을 종료한다. throw의 두번 째 매개변수를 생략하면 catch는 nil을 반환한다.


     

    word_list - File.open("wordlist")

    word_in_error catch (:done) do

         result =  [  ]
         while line = word_list.gets

              word = line.chomp

              throw (:done, word) unless word =~ /^\w+$/

              result << word 
         end

         puts result.reverse

    end


    if word_in_error 

         puts "Failed: '#{word_in_error}' found, but a word was expected"

    end



    실행결과


    Failed: '*wow*' found, but a word was expected


    다음 예제는 프롬프트에 !가 입력되었을때 사용자와의 대화를 끝내는 용도로 throw를 사용한다.


    def prompt_and_get(prompt)

         print prompt

         res = readline.chomp

         throw :quit_requested if res == "!"

         res    

    end



    catch :quit_requested do

         name = prompt_and_get("Name: ")

         age = prompt_and_get("Age: ")

         sex = prompt_and_get("Sex : ")

         #

    end


    위 예제에서 보듯 throw가 꼭 catch 블록과 같은 정적 범위에 있어야 할 필요는 없다. 












    끄읕





Designed by Tistory.