패키지와 모듈 — Gemfile이 go.mod가 됐을 때
Ruby의 require/gem 시스템 vs Go의 package/module 시스템
Ruby에서 외부 라이브러리를 쓰려면: Gemfile에 gem 'rails'를 추가하고 bundle install을 실행한다.
Go에서는: go get github.com/gin-gonic/gin을 실행하면 go.mod에 자동으로 추가된다.
Gemfile vs go.mod
Ruby의 Gemfile은 gem 이름과 버전 제약을 적는다: gem 'rails', '~> 7.0'
Go의 go.mod는 모듈 경로(보통 GitHub URL)와 버전을 적는다: require github.com/gin-gonic/gin v1.9.1
가장 큰 차이: RubyGems라는 중앙 레지스트리가 있고 gem install rails로 이름만으로 설치한다. Go는 중앙 레지스트리 없이 GitHub URL이 곧 패키지 식별자다.
require vs import
Ruby: require 'json' — 파일 이름 또는 gem 이름으로 로드.
Go: import "encoding/json" — 패키지 경로로 import. 사용하지 않는 import가 있으면 컴파일 에러. Ruby에서는 require를 했든 안 했든 에러가 안 난다.
디렉토리 = 패키지
Ruby에서는 파일 구조와 모듈/클래스 구조가 느슨하게 연결된다(Rails의 autoload가 이걸 처리). Go에서는 디렉토리 하나가 패키지 하나다. 같은 디렉토리의 모든 .go 파일은 같은 package 선언을 가져야 한다.
GOPATH → Go Modules
예전 Go는 GOPATH라는 고정 경로에 모든 코드를 넣어야 했다. Ruby로 치면 모든 프로젝트를 ~/ruby_projects/ 안에서만 개발하는 것과 같다. 지금은 Go Modules(go.mod) 덕분에 아무 데서나 개발할 수 있다. Bundler가 해결한 문제를 Go는 2019년에야 해결했다.
Ruby에서 Go로
Ruby: Gemfile + bundle install → Go: go.mod + go get
Ruby: require "json" → Go: import "encoding/json" (미사용 시 컴파일 에러)
Ruby: RubyGems 중앙 레지스트리 → Go: GitHub URL이 곧 패키지명
Ruby: 파일/모듈 느슨한 연결 (autoload) → Go: 디렉토리 = 패키지 (1:1 대응)
장점
- ✓ 패키지 다운로드가 빠르다 — 소스를 직접 가져오므로 빌드가 단순하다
- ✓ 미사용 import가 컴파일 에러 — 코드가 항상 깔끔하게 유지된다
단점
- ✗ GitHub URL 기반이라 리포지토리가 삭제/이동되면 의존성이 깨진다
- ✗ private 리포지토리 의존성 설정이 RubyGems 대비 번거롭다