Computer >> 컴퓨터 >  >> 프로그래밍 >> Ruby

코드 고고학으로 손쉽게 문제 해결하기

버그를 수정하다 보면 가장 빠르고 눈에 띄는 변경이 항상 최선의 선택은 아닙니다. 그리고 눈앞에 있는 코드만으로 전체 이야기를 알 수 없습니다. 쉬운 해결책을 넘어서려면 그런 결정이 내려졌는지 알아야 합니다. 즉, 코드 뒤에 숨겨진 역사를 이해해야 하는 것입니다. 코드를 자신 있게 변경하는 데 필요한 지식을 얻을 수 있는 훌륭한 방법 세 가지를 소개합니다.

git blame 활용하기

git blame을 사용하면 프로젝트 내 모든 코드 줄의 모든 버전을 추적해서, 해당 코드가 처음 작성된 시점까지 거슬러 올라갈 수 있습니다.

예를 들어 ActiveJob의 queue_name.rb 파일을 살펴보다가 queue_name_delimiter 속성이 정확히 무엇인지 궁금해졌다고 가정해 봅시다.

activejob/lib/active_job/queue_name.rb
included do
  class_attribute :queue_name, instance_accessor: false
  class_attribute :queue_name_delimiter, instance_accessor: false

  self.queue_name = default_queue_name
  self.queue_name_delimiter = '_' # 기본 구분자를 '_'로 설정
end

여기에 git blame을 실행할 수 있습니다.

$ git blame queue_name.rb

...
da6a86f8 lib/active_job/queue_name.rb           (Douwe Maan               2014-06-09 18:49:14 +0200 34)     included do
1e237b4e activejob/lib/active_job/queue_name.rb (Cristian Bica            2014-08-25 17:34:50 +0300 35)       class_attribute :queue_name, instance_accessor: false
11ab04b1 activejob/lib/active_job/queue_name.rb (Terry Meacham            2014-09-23 15:51:44 -0500 36)       class_attribute :queue_name_delimiter, instance_accessor: false
11ab04b1 activejob/lib/active_job/queue_name.rb (Terry Meacham            2014-09-23 15:51:44 -0500 37)
...

각 줄마다 다음 정보를 순서대로 확인할 수 있습니다.

  • 해당 줄을 가장 최근에 변경한 리비전(예: 11ab04b1)
  • 그 커밋의 작성자 이름
  • 변경이 이루어진 날짜

그 코드 줄에 대해 더 자세히 알고 싶다면 리비전 번호가 필요합니다. 해당 ID(11ab04b1 부분)를 git showgit log에 넘기면 됩니다.

$ git show 11ab04b1

commit 11ab04b11170253e96515c3ada6f2566b092533a
Author: Terry Meacham <zv1n.fire@gmail.com>
Date:   Tue Sep 23 15:51:44 2014 -0500

    Added queue_name_delimiter attribute.

    - Added ActiveJob::Base#queue_name_delimiter to allow for
      developers using ActiveJob to change the delimiter from the default
      ('_') to whatever else they may be using (e.g., '.', '-', ...).

    - Updated source guide to include a blurb about the delimiter.

diff --git a/activejob/lib/active_job/queue_name.rb b/activejob/lib/active_job/queue_name.rb
index d167617..6ee7142 100644
...

훌륭하죠! 이제 그 변경 사항이 무엇이고 왜 유용한지 조금 더 알게 되었고, 이전에 놓쳤을 수도 있는 Rails 가이드의 관련 부분도 확인하게 됩니다.

여기서는 운이 좋았습니다. 찾으려던 정보를 바로 발견했으니까요. 하지만 git blame은 해당 줄이 변경된 가장 최근 이력만 보여줍니다. 때로는 두세 커밋을 더 거슬러 올라가야 원하는 것을 찾을 수 있습니다.

더 오래된 커밋을 보려면 git blame을 다시 실행하면 됩니다. 단, 이번에는 방금 찾은 커밋의 바로 이전 리비전을 인자로 넘깁니다. (git에서는 리비전 뒤에 ^를 붙여 '특정 커밋의 이전 커밋'을 표현할 수 있습니다. 예: 11ab04b1^)

$ git blame 11ab04b1^ queue_name.rb

...
da6a86f8 lib/active_job/queue_name.rb           (Douwe Maan               2014-06-09 18:49:14 +0200 33)     included do
1e237b4e activejob/lib/active_job/queue_name.rb (Cristian Bica            2014-08-25 17:34:50 +0300 34)       class_attribute :queue_name, instance_accessor: false
94ae25ec activejob/lib/active_job/queue_name.rb (Cristian Bica            2014-08-15 23:32:08 +0300 35)       self.queue_name = default_queue_name
...

$ git blame 1e237b4e^ queue_name.rb
... 이런 식으로 계속 ...

하지만 이 방식은 상당히 번거롭습니다.

대신 여러분이 사용하는 에디터의 기능을 살펴보세요. 대부분의 에디터는 git blame으로 히스토리를 추적하는 과정을 쉽게 만들어 줍니다. 예를 들어 Emacs에서는 코드를 git blame으로 연 뒤 커서를 특정 줄에 놓고, a 키를 눌러 그 줄에 영향을 준 각 변경 사항을 하나씩 거슬러 올라갈 수 있으며, lD 키로 커밋에 대한 자세한 정보를 볼 수 있습니다.

혹시 여러분 팀이 커밋 메시지에 이슈 번호나 풀 리퀘스트를 함께 적어두나요? 그렇다면 git blame을 통해 한 줄의 코드에서 커밋으로, 그리고 그 커밋에 관한 논의까지 손쉽게 이동할 수 있습니다. 바로 그 논의에서 진짜 유용한 정보들을 찾을 수 있습니다.

GitHub Issues 검색하기

얼마 전 저는 Rails 4.2에서 respond_with가 제거되었다는 것을 알게 되었습니다. 문서에는 제거되었다는 사실만 명확히 나와 있을 뿐, 그 이유는 설명되어 있지 않았습니다.

GitHub의 이슈 검색창 뒤에는 엄청난 양의 유용한 지식이 숨겨져 있습니다. 어떤 기능이 왜 제거되었는지 알고 싶다면, 팀이 제거를 결정하면서 나눴던 논의보다 좋은 학습 자료는 없습니다.

Rails의 GitHub 저장소에서 respond_with를 검색하면 흥미로운 스레드들을 찾을 수 있습니다. 제거 이유를 파악하려고 한다면 아마 특정 스레드에 도달하게 될 텐데, 안타깝게도 그 스레드는 어떻게 제거되었는지만 설명하고 제거되었는지는 다루지 않습니다.

하지만 그 스레드를 끝까지 읽다 보면, 실제로 respond_with 제거를 논의한 본래 스레드를 가리키는 댓글을 발견하게 됩니다. 바로 그곳에 진짜 핵심 정보가 있는 것이죠!

git blame과 마찬가지로, 처음부터 딱 원하는 정보를 찾지 못할 수도 있습니다. 참조를 따라가고, 댓글을 읽고, 링크를 클릭해야 할 때도 있습니다. 하지만 GitHub 이슈 검색은 올바른 출발점을 잡아주며, 약간의 호기심과 탐구심만 있다면 결국 원하는 답을 찾을 수 있습니다.

직접 질문하기

아쉽게도 프로젝트에 관한 모든 지식이 히스토리, 이슈, 풀 리퀘스트에 기록되어 있는 것은 아닙니다. 모든 것이 문서화되어 있지 않습니다.

따라서 그 코드를 처음 작성한 사람을 찾을 수 있다면 직접 물어보세요. 어떤 결정에 이르게 된 개발 문화와 아이디어를 알게 되고, 어디에도 기록되지 않았을 프로젝트의 역사를 배우게 됩니다. 또한 당시에는 선택되지 않았던 대안들에 대해서도 들을 수 있는데, 그중 일부는 지금 시점에서 시도해볼 만한 가치가 있을지도 모릅니다.

쉬운 방법은 위험할 수 있다

때로는 수정이 너무나 쉬워 보입니다. 딱 한 곳에서 이 예외 하나만 처리하면 퇴근할 수 있다고요!

하지만 이해하지 못한 코드를 변경하는 것은 위험합니다.

그러니 어떤 코드 줄이 어색해 보이거나, 어떤 결정이 이상해 보이거나, 어떤 호출이 불필요해 보일 때는 고고학자의 모자를 쓰세요. 그 코드에 대해 할 수 있는 모든 방법으로 최대한 많이 알아내야 합니다. 그래야 의도를 가지고 코드를 변경할 수 있고, 문제를 근본적으로 해결할 수 있습니다.