Rails 앱을 개발하다 보면 수많은 젬(gem)을 사용하게 됩니다. 어떤 젬들은 마치 마법처럼 느껴지기도 하는데요. 그렇다면 그 마법은 대체 어떻게 일어나는 걸까요?
사실 대부분의 젬이 하는 일은 여러분이 할 수 없는 것이 아닙니다. 그저 루비(Ruby) 코드일 뿐입니다. 물론 때로는 꽤 복잡한 루비 코드이긴 하지만요. 하지만 그 코드를 직접 탐색해 보면, 마법의 근원이 어디에 있는지 조금씩 이해하게 됩니다.
소스 코드 찾기
젬이 어떻게 동작하는지 이해하려면 먼저 그 코드를 찾아야 합니다.
특정 메서드에 대해 더 알고 싶다면 소스를 쉽게 찾는 방법이 있습니다. 바로 method와 source_location입니다. 예시를 볼까요?
irb(main):001:0> ActiveRecord::Base.method(:find).source_location
=> ["/usr/local/lib/ruby/gems/2.1.0/gems/
activerecord-4.2.0.beta4/lib/active_record/core.rb", 127]
그런데 궁금한 메서드가 하나가 아니라 여러 개라면 어떻게 할까요?
Rails 앱 디렉터리에서 콘솔을 열어두었다면, 다음 명령어로 젬의 코드에 곧바로 접근할 수 있습니다.
~/Source/gem_example[master] jweiss$ bundle open rack
해당 젬이 Gemfile에 등록되어 있다면, bundle open rack 명령으로 rack 젬 전체를 에디터에서 열 수 있습니다. 젬 안의 모든 파일을 편안하게 둘러볼 수 있죠.
어디서부터 시작할까?
젬의 코드 위치를 알았으니, 이제 어떻게 이해하기 시작해야 할까요?
lib/active_record.rb 파일만 읽으면서 activerecord의 동작 방식을 파악하려 들면 아무 성과도 얻지 못합니다. 그 파일에는 autoload와 require 구문만 가득할 뿐입니다.
젬은 앱에서 실제로 어느 정도 사용해 본 후에 이해하는 것이 가장 쉽습니다. 젬이 어떤 작업을 대신 해주는지 어느 정도 감을 잡고 나면, 어떤 클래스와 메서드부터 살펴봐야 할지 자연스럽게 그려지기 때문입니다.
흥미로운 메서드 이름들을 몇 개 확보했다면, source_location, 에디터의 '프로젝트 내 찾기' 기능, 혹은 커맨드 라인의 ag(the silver searcher)를 활용해 해당 메서드가 어디에 정의되어 있는지 추적할 수 있습니다. 이제부터가 진짜 재미있는 부분입니다.
젬의 코드는 여러분의 컴퓨터에 있죠? 즉, 원하는 대로 자유롭게 수정할 수 있다는 뜻입니다! 심지어 망가뜨려도 아무도 알 수 없습니다.
저는 젬의 동작 방식을 파악할 때 단순히 코드만 읽지 않습니다. 젬 안에 puts 문을 추가해 값을 출력해 보고, 예외(exception)를 던져 앱이 특정 라인에 어떻게 도달했는지 추적하고, 코드를 이리저리 고쳐 보면서 왜 저런 식으로 작성했는지 스스로 검증합니다.
마술의 비밀을 한번 알고 나면, 더 이상 마법 같지 않습니다. 게다가 낯선 상황에서 그 코드가 어떻게 동작할지 추측할 필요도 없습니다. 직접 눈으로 확인할 수 있으니까요.
사용 후 깔끔하게 정리하기
젬 코드를 마음대로 수정한 뒤에는 앱 상태가 상당히 엉망이 될 수 있습니다. 아예 실행조차 되지 않을 수도 있죠! 설령 실행된다 해도, 추가해둔 수많은 puts 문이 콘솔을 도배할 것입니다.
다행히 RubyGems에는 원래 상태로 빠르게 되돌리는 방법이 있습니다.
~ jweiss$ gem pristine activerecord -v 4.2.0
Restoring gems to pristine condition...
Restored activerecord-4.2.0
혹시 어떤 젬을 수정했는지 기억나지 않는다면, 그리고 인내심이 충분하다면 다음 명령어를 사용해 보세요.
~ jweiss$ gem pristine --all
이 명령을 실행하면 설치된 모든 젬이 처음 설치했던 시점의 원래 상태로 되돌아갑니다.
무엇부터 탐험해 볼까요?
젬 속의 코드를 직접 찾아 읽고 탐험하다 보면, 평소 의존하던 코드를 훨씬 깊은 수준에서 이해하게 됩니다. 더 이상 가정과 추측에 의존하지 않아도 되는 것이죠.
이 글은 원래 제 뉴스레터 구독자에게만 발송된 글입니다. 매주 금요일 이런 글을 받아보고 싶다면 지금 구독하세요!