코드 주석
GitLab v19.4요약
코드 자체로 설명되게 작성하여 추가 주석을 줄이는 것이 첫 번째 목표입니다. 코드만으로 충분히 설명되지 않는다면, 코드만으로는 표현할 수 없는 컨텍스트와 근거를 제공하는 데 주석이 중요한 역할을 합니다. 코드 주석은 코드 자체만큼이나 코드의 일부입니다.
핵심 원칙#
코드 자체로 설명되게 작성하여 추가 주석을 줄이는 것이 첫 번째 목표입니다. 설명적인 메서드 이름, Ruby의 표현력 활용, 키워드 인수 사용, 작고 단일 목적을 가진 메서드 작성, 관용적 규약 준수, enum 사용 등으로 이를 강화할 수 있습니다.
코드만으로 충분히 설명되지 않는다면, 코드만으로는 표현할 수 없는 컨텍스트와 근거를 제공하는 데 주석이 중요한 역할을 합니다.
코드 주석은 코드 자체만큼이나 코드의 일부입니다. 코드가 변화하거나 시스템에 대한 이해가 깊어짐에 따라 주석도 유지 보수하고 업데이트하며 다듬어야 합니다.
따라야 할 핵심 원칙은 다음과 같습니다.
- 주석은 참조하는 코드와 최대한 가까운 위치에 둡니다
- 주석은 충실하되 중복은 피합니다
- 이 코드를 다음에 읽는 사람은 컨텍스트가 전혀 없고 이해할 시간도 부족하다고 가정합니다
코드 주석은 "무엇"이나 "어떻게"가 아니라 "왜"에 더 집중해야 합니다#
무엇을 하는지는 코드 자체가 명확하게 드러내야 합니다. 주석으로 기능을 설명하면 유지 보수 부담이 늘어납니다. 코드가 바뀌면 주석이 낡은 내용이 되어 혼란을 일으킬 수 있기 때문입니다. 대신 주석은 특정 결정을 내린 이유나 특정 접근 방식을 택한 이유를 설명해야 합니다.
예를 들면 다음과 같습니다.
- 시스템의 제약을 우회하는 경우
- 바로 드러나지 않는 예외 상황을 처리하는 경우
- 도메인 지식이 깊이 필요한 복잡한 비즈니스 로직을 구현하는 경우
- 레거시 시스템의 제약을 처리하는 경우
좋은 주석의 예시입니다.
# Note: We need to handle nil values separately here because the external
# payment API treats empty strings and null values differently.
# See: https://api-docs.example.com/edge-cases
def process_payment_amount(amount)
# Implementation
end
불필요한 주석의 예시입니다.
# Calculate the total amount
def calculate_total(items)
# Implementation
end
상위 수준 코드 주석 및 클래스/모듈 수준 문서화#
GitLab 코드베이스에는 여러 곳에서 재사용되는 라이브러리가 많습니다.
이 중 일부 라이브러리(예: ExclusiveLeaseHelpers)는
내부 구현이 복잡해서, 읽고 그 라이브러리 사용에 따른 영향을 파악하는 데 시간이 많이 걸립니다.
마찬가지로 일부 라이브러리에는 파라미터 이름만 읽어서는 이해하기 어려운
중요한 결과를 가져오는 옵션이 여러 개 있습니다.
이러한 라이브러리를 개발자용 별도 Markdown 파일로 문서화할지, 클래스·모듈·메서드 위의 주석으로 문서화할지에 대한 엄격한 지침은 없으며, GitLab 코드베이스 전반에 두 방식이 섞여 있습니다. 어느 쪽이든 문서의 가치는 라이브러리가 널리 쓰일수록 커지고, 라이브러리의 구현과 인터페이스가 자주 바뀔수록 작아진다고 봅니다.
후속 조치를 위한 주석#
향후에 처리해야 할 내용을 코드에 주석으로 추가할 때는 기술 부채 이슈를 생성합니다. 그리고 작성한 코드 주석에 그 이슈 링크를 넣습니다. 이렇게 하면 다른 개발자가 해당 주석이 아직 유효한지, 처리하려면 무엇이 필요한지 빠르게 확인할 수 있습니다.
예시입니다.
# Deprecated scope until code_owner column has been migrated to rule_type.
# To be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/11834.
scope :code_owner, -> { where(code_owner: true).or(where(rule_type: :code_owner)) }
클래스 및 메서드 문서화#
새로 추가하거나 수정한 모든 메서드에는 그 동작을 짧게 설명하는 문서를 작성하고, 파라미터와 반환값에는 YARD 구문을 사용합니다.
- 각 인수에는
@param을, 명시적 반환값이 있는 메서드에는@return을 작성합니다. - 설명과 YARD 태그는 빈 줄로 구분합니다.
- 다른 메서드나 클래스를 참조할 때는 링크 가능한 참조(예:
{Order#order_ids_by_email})를 사용하고@see태그도 함께 고려합니다.
예시입니다.
class Order
# Finds order IDs associated with a user by email address.
#
# @param email [String, Array] User's email address
# @return [Array]
def order_ids_by_email(email)
# ...
end
end
메서드의 반환값을 사용하지 않는다면 YARD @return 타입을 void로 표기하고
메서드가 명시적으로 nil을 반환하도록 합니다. 이 패턴은 반환값을 사용하지 말아야 함을
분명히 하고, 체이닝이나 대입에서 실수로 사용하는 상황을 막아 줍니다.
예를 들면 다음과 같습니다.
class SomeModel < ApplicationRecord
# @return [void]
def validate_some_field
return unless field_is_invalid
errors.add(:some_field, format(_("some message")))
# Explicitly return nil for void methods
nil
end
end
자세한 컨텍스트와 정보는 머지 리퀘스트 코멘트를 참고합니다.