최근 펄을 이용하여 프로젝트를 진행했습니다. 펄로 코딩을 하다보면 자바에서는 경험하지 못했던 몇가지 신선한 경험을 하게 됩니다. 이번 사건도 그 중 하나였던 것 같습니다.

제가 만든 펄 스크립트의 안정성을 위해 사용자가 입력한 내용을 한번 더 확인시켜줘야겠다는 생각이 들었습니다. 그래서 아래와 같이 코드를 만들었습니다. 사용자로부터 입력을 받아 Y나 y를 입력했을 경우에만 주실행로직을 수행하는 코드입니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $confirmation = <STDIN>;
chomp($confirmation);
if ($confirmation eq "Y" || $confirmation eq "y") {
    # 약 40줄 정도 되는 주요 처리 코드
   ...
   ...
   ...
}
# 코드의 끝
그런데 실제 코딩을 하고 나니 실행코드가 조건문 안에 들여쓰기 되어 갇혔다는 것을 발견했습니다. 그것도 40줄이나 말입니다 안정성을 향상 시키기 위해 들어간 선택적인 코드 때문에 이런 일이 발생 한 것은 다소 불합리해 보였습니다. 왠지 손님이 주인을 밀어내는 느낌이라고나 할까요?

거기에다가 제가 본 펄 강의에는 열악한 환경의 터미날을 이용할 때를 대비하여 코드의 가로길이가 80자를 넘어가지 않게하라고 강조했습니다. 80자가 넘어가면 코드를 보기가 힘들어지고 따라서 수정하기가 어려워진다고 하더군요. 들어쓰기는 가로길이를 늘어나게 하기 때문에 이러한 이유로도 제거되야 하는 것이 마땅해 보였습니다.

그래서 코드를 아래와 같이 수정했습니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $confirmation = <STDIN>;
chomp($confirmation);
exit if ($confirmation ne "Y" && $confirmation ne "y");

# 약 40줄 정도 되는 주요 처리 코드
...
...
...
# 코드의 끝
"$confirmation이 Y이거나 y이어야 함"을 "$confirmation이 Y가 아니고 y도 아닐 때"라는 부정조건으로 바꾸고 만약 해당 조건이 만족했을 때는 즉시 스크립트를 종료하도록 처리 한 것입니다.

이렇게 코드를 작성하니 40줄의 처리 코드는 조건문에서 빠져나올 수가 있었습니다. 그런데 가만히 보다보니 또 문제가 보였습니다. 그것은 새롭게 바뀐 조건식이 직관적이지 않다는 것입니다. 바뀐 조건식 'Y가 아니고 y도 아니어야 한다'라는 것은 처음에 있었던 "Y거나 y어야 함'보다 이해하기 어렵게 느껴졌습니다.

그래서 아래와 같이 한번 더 코드를 수정했습니다.
print($sampleString."' 이 정말 맞습니까? (Y/N) ");
my $inputFromUser = <STDIN>;
chomp($inputFromUser);
my $confirmation = $inputFromUser eq "Y" || $inputFromUser eq "y";
exit if ($confirmation == 0); #펄은 true/false 대신 1/0 개념이 사용 됨.

# 약 40줄 정도 되는 주요 처리 코드
...
...
...
# 코드의 끝
결국 이렇게 수정함으로 인해 직관적인 긍정조건을 사용 하면서도 40줄을 들여쓰기로부터 해방시킬 수 있었습니다. 소소하지만 재밌는 경험이였다고 생각합니다.

WRITTEN BY
차민창
르세상스 엔지니어가 사회를 이끌어나가는 상상을 하며!

트랙백  1 , 댓글  17개가 달렸습니다.
  1. 조건문에서 긍정적으로 할거냐? 부정적으로 할거냐는 재밌는 요소입니다. 반드시 긍정적으로 해야 직관적인 것은 아닙니다. 부정적이 더 직관적인 경우도 많거든요. "조건만족하지 않으면 하지 마라!"식의 표현입니다.

    저같은 경우는 위에 코드가 코드량도 적고, 더 이해하기 쉽네요...^^
    • 예 덧글이 현재 두 개 달렸는데 각각 첫번째, 두번째가 더 좋아보인다는 의견이네요 ㅋ

      말씀하신 대로 부정적이 직관적인 경우는 아마 있을 것 같긴 합니다. 그렇기 때문에 모든 경우에 긍정이 직관적이라고는 말할 수 없을 것 같고요.

      하지만 저는 위 경우라면 긍정조건이 훨씬 직관적이라고 생각했는데 이 부분은 사람에 따라 다른 부분인 것 같네요. 이거 다른 분들께도 한번 여쭤봐서 업데이트를 하던지 하겠습니다 ㅋ
  2. 전 차라리 첫번째가 더 낫다고 보입니다. 블럭 안에 들어가는 코드가 많으면 다른 서브루틴으로 분리해서 호출해도 될거구요. 코드 중간에 exit를 넣는건 오히려 코드를 보는 다른사람에게는 혼돈을 가져다 줄 수 있을것 같네요.

    그리고
    if ($confirmation eq "Y" || $confirmation eq "y")
    조건문은
    if ( uc($confirmation) eq "Y")
    이렇게 줄여쓰면 되겠습니다.
    • 들여쓰기 때문에 발생한 일인만큼 서브루틴 도입도 좋은 해결책이 될 수 있겠네요. 또한 작업 단위에 이름도 부여할 수 있으니 일석이조인 것 같습니다.

      'exit가 들어가면 혼돈을 가져온다'라는 말씀은 개인적으로는 감이 쉽게 안오네요. 혹시 조금 더 설명해주실 수 있으시면 설명 부탁드립니다.

      p.s uc는 오늘 aero님 덕분에 배웠습니다 ㅋ
  3. exit는 개인적인 의견입니다. 어떤 다양한 조건이 있다면 조건 처리는 swtich구문처럼 각 조건에 다른 처리를 하고 아니면 default를 통해 처리가 끝나는 순서처럼 가는게 좋아 보인다는거죠. 더이상 처리할것이 없다고 해도 exit는 너무 급진적으로 보인다고나 할까요..

    만약에 프로그램 끝에 종료되었습니다. 라는 메시지를 찍어주고 싶다면 프로그램 맨끝에 해당 메시지를 찍는 구문을 넣고 모든 경우에 대해 그 구문을 통해서 끝나게 하려면 조건에 어떤 조건식을 거치더라도 그 구문 바로앞으로 플로우가 흘러가도록 만들어야 할겁니다. 그런데 저렇게 프로그램 중간에 exit를 쓴다면 중복으로 그 메시지를 찍는 구문을 추가한 다음 exit해야 되겠죠.
    • 예 그렇군요. 말씀하신 대로 급진적으로 보일 수 있겠네요. 이 부분은 좀더 곰곰히 생각해봐야겠습니다. 나중에 혹시 생각이 잘 정리되면 블로그에 글을 써서 올리도록 하겠습니다.

      좋은 의견 주셔서 진심으로 감사드려요. 앞으로 많은 소통 있었으면 좋겠습니다.
  4. 아, 이거 들여쓰기.
    저도 얼마전에 이 문제로 고민했었는데, 이렇게 글로 정리된것을 보니 새삼 다시 생각할수 있는 기회가 생기네요.
    요즘 리눅스 C 공부하면서 코딩할때 그랬었는데요.
    리눅스 시스템 C 소스들을 참고로 보니까, 그 코드들도 보면 대부분, 포스팅에서 두번째 올리신 저 코드처럼, [not체크-종료] 하도록 되어있는 검증 코드가 항상 상단에 주욱 있고, 실제 수행되어야할 메인루틴은 아래쪽에 아무런 블럭에도 쌓여있지 않은채 놓여있더라고요.
    처음엔 이런 방식이 왠지 코드의 흐름을 중간에 끊것이 아닐까 생각하고, 첫번째 올리신 코드처럼 조건문 블럭안에 메인루틴을 놓고 들여쓰기 하고 그랬어요.
    근데 이렇게 하니까 중간에 수정하면서 사소한 검증부분 하나씩 늘어날때마다 들여쓰기도 하나씩 더 늘어나고... 결국에는 더 알아보기 힘든 괴악한 코드가 되더라고요.
    vi 편집기로 코딩하다보니 역효과가 더 심해서... 마우스로 다이랙트하게 접근도 안되니 끝자락부분 하나 수정하는데 몇번을 텝이동을 하게 되는지 원....
    그래서 루틴을 함수로 분리할까 했는데, 이거 함수추가해서 연결하기도 되게 번거롭고 넘어갈 argument 도 많아서 어려운데다가, 이런 사소한 검증코드때문에 이렇게까지 수고해야한다는게 억울해서, 결국은 저도 포스팅에서 두번째 수정하신 저 코드처럼 검증-exit 를 추가해서 분리를 하게 되었어요.
    구조적으로 깔끔한코드보다는, 그냥 사람이 볼때 코드량 적고 화면이 한눈에 들어오는 코드가 좋은거 같아요.

    * 세번째 코드와 관련된 직관적인 조건문 코드에 대한건데요.
    저런식으로 체크-종료하는 짧은 코드를 작성하는거라면, 굳이 조건을 or 나 and로 연결하지말고...

    exit if($inputFromUser ne "Y");
    exit if($inputFromUser ne "y");

    이렇게 한문장씩 끊어쓰는것도 괜찮은 방법이 되지않을까 하는 생각을 해봤어요.
    물론 이렇게 하면 exit라는 최종실행루틴이 여러부분으로 갈라지고, 쓸대없는 중복이 많아져서 찜찜한 느낌이 남긴하는데, 일단 직관성이라는 주제에 대한 이야기니까요.

    아, 쓰다보니 덧글이 쓸대없이 너무 길어졌네요. 블로그하나띄우고 트랙백할걸 ㅋ
    • 난 C코딩이나 vi로 개발은 한 경험이 많지 않아서 잘 몰랐던 부분인데 좋은 경험 공유해줘서 고마워.

      구조적으로 깔끔한 코드와 사람이 볼 때 코드량 적고 화면이 한눈에 들어오는 코드 중에 한눈에 들어오는 코드가 좋은 것 같다고 말했는데, 그렇다면 구조적으로 코드를 만드는 목적이 무엇인가 생각하게 되는 것 같아.

      구조적 코드라면 유지보수성의 향상이라는 목적도 있겠지만 읽는 사람이 보기 좋게 하려는 의도도 있지 않을까? 그래서 조금 정리해서 '큰 관점에서는 구조적 코드를 지향하되 작은 부분에서는 가독성의 향상을 위해 구조적인 부분을 약간 희생할 수 있다' 정도로 정리하면 어떨까?

      마지막으로 세번째 코드에 대해 대안을 제시해주었는데 지훈이가 말한 대로 직관성을 위해서 조건을 분해해서 나누는 것도 좋은 방법이 될 것 같아.

      다만

      exit if($inputFromUser ne "Y");
      exit if($inputFromUser ne "y");

      위와 코드는 OR 조건일 때만 사용할 수 있을 것 같네.ㅋㅋ
    • 아 그러고보니 OR밖에 안되겠네요 ㅎㅎ 부끄러워라.
  5. 복잡성 최소화를 따라가면 됩니다.
    function(A a) {
    if ( a != null ) {
    blah
    blah
    }
    }

    이렇게가 아니고
    function(A a) {
    if ( a == null ) {
    return;
    }
    blah
    blah
    }
    이런식으로 말이죠. 빨리 구역을 끝낼수 있는 쪽, 복잡성을 떨어 트려주는 쪽을 먼저 선택하면 됩니다.
    • 말씀하신 대로 복잡성을 떨어 트려주는 쪽을 택하자라는 말씀에는 깊히 공감합니다. 그런데 이 복잡성에 대한 정의가 명확하지 않고, 사람마다 복잡성에 대한 기준이 틀린 것 같네요. 따라서 복잡성이 주관에 영향을 받는다는 사실이 어려운 문제가 되지 않을까 생각합니다.

      좋은 의견 주셔서 감사합니다. 앞으로 많은 교류 있었으면 좋겠습니다.
  6. Perl에는 if 말고도 unless도 있습니다. exit unless $confirmed;

    함수의 exit point가 한 곳인게 좋으냐 여러 곳이어도 좋으냐 하는 문제죠. 너무 많지만 않으면 조건 검사하고 바로 탈출 해버리는 것이 가독성이 더 좋더군요. 특히 precondition 검사할 때는요. 전에는 들어오는 곳이 한 군데이면 나가는 곳도 한 군데이어야 한다고 생각을 했었는데 꼭 그런 것은 아닌 것 같아요.
    • 예 그렇군요. 저도 예전 한 때 자바 코딩을 하면서 return은 코드에 마지막에 위치하도록 하는 코딩을 지향하던 적이 있었는데, 그렇게 하면 코드가 많아지고 오히려 복잡해지는 것을 느낀 후에는 그냥 return을 사용하고 있습니다.

      말씀하신 대로 결국은 '함수의 exit point가 한 곳인게 좋으냐 여러 곳이어도 좋으냐 하는 문제'이네요 ㅋㅋ

      기본적으로는 exit point를 한 곳으로 쓰는 것을 지향하되, 코드의 가독성과 복잡성을 감소시키는 목적이 있을 때는 여러 exit point를 사용해도 좋다라고 정리하고 싶네요.
  7. 오늘 스터디 하면서 Implementation Patterns 3장 Principles 부분을 보다 이 예가 여러 번 생각났습니다. 보고 계신 것 같던데 뭔가 건질게 있을 겁니다.
  8. "들여쓰기 최소화" 자체는 거의 principles에 근접하는 명제라는 생각이 드네요~ 여러가지 코딩스킬으로 들여쓰기는 최소화하는 것이 좋겠죠.
    • 예 들여쓰기 최소화를 스터디 하는 책에서 소개 된 여러 가치와 원칙에 견주어서 집중 분석해보고 싶네요 ㅋ
      다 공부하고나면 한번 시도해보아야겠어요.
secret