DSL스러운 코딩을 위한 세 가지 핵심 전략
발표자는 DSL을 단순히 ‘대단한 사람들이 만드는 것’이 아닌, Ruby 개발자들이 일상적으로 활용하여 코드의 가독성과 유지보수성을 높일 수 있는 코딩 기술의 하나로 제시하며, DSL스러운 코드를 작성하는 구체적인 세 가지 방법을 소개했습니다.
1. 선언적 기술 (Declarative Description)
-
개념: ‘무엇을 해라’는 명령형 방식 대신, ‘무엇이다’와 같이 객체의 상태나 성질을 기술하는 방식입니다. Rails의
validates_presence_of :name이나before_filter :find_group,has_many :children등이 대표적인 예시입니다. -
특징: 리시버(self)를 생략하고 괄호를 사용하지 않아 프로그램 코드보다는 전용 언어처럼 보이게 합니다.
- 구현: 클래스 내에서 해당 클래스의 성질을 나타내는 메서드(클래스 메서드)를 정의하여 구현합니다. 예를 들어,
self.money = 0대신poor라는 선언적 메서드를 사용하거나,include Product대신acts_as_product와 같은 메서드를 정의하여 모듈을 포함하는 방식을 활용합니다.acts_as_product와 같은 클래스 메서드는 일반적으로Object클래스 또는 상위 클래스에 정의하여 모든 하위 클래스에서 호출 가능하게 합니다. 이는 Rails의 이니셜라이저 등을 통해 애플리케이션 로드 초기에 실행되어야 합니다.
- 명명 규칙: 선언적 기술에는 형용사나 과거분사(
attached,recorded) 또는 3인칭 단수 현재형(has,is,validates)을 사용하고, 일반 메서드에는 동사 원형(have,use,validate)을 사용하는 것이 좋습니다.
2. 블록의 활용 (Utilizing Blocks)
-
개념: Ruby의 블록은 복잡한 데이터 구조를 표현하거나, 블록 내부에 작성된 코드에 특정 스코프를 적용하는 데 유용합니다. Rake의 태스크 정의나 Rails 폼 헬퍼 등이 블록을 활용하는 대표적인 사례입니다.
-
구현: 특정 개념을 나타내는 최상위 메서드(예:
game)를 정의하고, 이 메서드가 블록을 인수로 받아 내부에서 객체를 생성한 후 블록에 전달하여 실행합니다. 이를 통해 블록 내부에서 해당 객체의 메서드(예:uses,deals)를 호출할 수 있게 합니다. -
고급 활용:
yield대신instance_exec를 사용하면 블록에 인수를 명시적으로 전달하지 않고도, 블록이 특정 객체의 컨텍스트에서 실행되도록 하여 더욱 DSL스러운 표현을 가능하게 합니다.
3. 특정 개념을 나타내는 메서드 (Methods Representing Specific Concepts)
-
개념: 명사 대용 메서드나 다른 언어의 개념에 직접 대응하는 메서드를 활용하여 코드의 의미를 명확하게 만듭니다. Rails의
url헬퍼나 HTML 태그를 나타내는submit, RJS의assert등이 이에 해당합니다. -
고려사항: 실용성과 타당성 사이의 균형을 유지하는 것이 중요하며, 지나치게 영어처럼 보이게 하려는 시도는 지양해야 합니다.
일반적인 DSL 코딩 팁
-
인수에 기본값을 설정하여 인수를 생략할 수 있도록 합니다.
-
해시를 사용하여 호출 코드의 가독성을 높입니다.
-
심볼을 적극적으로 활용하여 의미를 명확히 합니다.
-
메서드 이름을 단순히 처리 내용 대신 반환 값이나 스코프를 나타내는 방식으로 고안합니다.