이 글에서는 루비(Ruby)의 속성 접근자인 attr_accessor에 대해 자세히 알아봅니다.
바쁘신 분들은 아래 예제 섹션으로 바로 내려가셔도 좋습니다.
하지만 그 전에 먼저 설명하고 싶은 것이 있습니다.
왜 속성 접근자를 사용해야 하는가?
속성 접근자가 필요한 이유
인스턴스 변수를 가진 클래스가 있고, 이 변수를 클래스 외부로 노출하고 싶다고 가정해 봅시다.
어떻게 해야 할까요?
바로 메서드를 정의해야 합니다.
인스턴스 변수에는 오직 메서드를 통해서만 접근할 수 있습니다.
그렇지 않으면 에러가 발생하기 때문입니다.
다음 예제를 살펴보세요:
class Food
def initialize(protein)
@protein = protein
end
end
bacon = Food.new(21)
bacon.protein
# NoMethodError: undefined method `protein'
NoMethodError는 적절한 설정 없이 protein 값을 요청할 때 발생하는 에러입니다.
그렇다면 해결책은 무엇일까요?
게터(Getter) 메서드 직접 만들기
다음과 같이 메서드를 직접 정의할 수 있습니다:
class Food
def protein
@protein
end
end
bacon.protein
# 21
다른 객체 지향 언어에서는 이를 "게터(getter)" 메서드라고 부릅니다. 인스턴스 변수의 값을 가져오는 역할을 하는 메서드죠.
세터(Setter) 메서드 직접 만들기
값을 변경하고 싶을 때도 있습니다.
이 경우에는 별도의 메서드가 하나 더 필요합니다:
class Food
def protein=(value)
@protein = value
end
end
bacon.protein = 25
객체 안으로 통로를 열어 값에 접근하고 변경할 수 있게 하는 것이라고 상상하면 이해하기 쉽습니다.
자, 여기서 질문: 이런 메서드를 더 편리하게 정의하는 방법은 없을까요? 일종의 단축 문법처럼요?
네, 있습니다! 🙂
바로 attr_accessor가 등장하는 순간입니다.
Ruby attr_accessor 예제
attr_accessor를 사용하면 루비에게 이런 메서드들을 자동으로 생성해 달라고 요청할 수 있습니다.
사용 방법은 다음과 같습니다:
class Food attr_accessor :protein def initialize(protein) @protein = protein end end
이 한 줄에 주목하세요:
attr_accessor :protein
이것은 다른 메서드들을 대신 만들어 주는 루비 메서드입니다.
어떤 메서드들을 만들까요?
이 예제에서는 다음 두 가지가 생성됩니다:
protein— 값을 읽는 게터 메서드protein=— 값을 변경하는 세터 메서드
앞서 우리가 직접 작성했던 메서드들과 정확히 동일한 기능을 합니다.
하지만 이제 일일이 타이핑할 필요가 없습니다.
바로 단축 문법이니까요!
attr_accessor vs attr_reader vs attr_writer 차이점
attr_accessor 외에도 다른 종류의 접근자들이 있습니다.
정확히 세 가지입니다:
attr_accessorattr_readerattr_writer
그렇다면 이들의 차이점은 무엇일까요?
attr_accessor는 읽기(reader)와 쓰기(writer) 메서드를 모두 생성합니다.
attr_reader는 읽기 메서드만 생성합니다.attr_writer는 쓰기 메서드만 생성합니다.
즉, attr_reader를 사용하면 값을 읽을 수만 있고 변경할 수 없으며, attr_writer를 사용하면 값을 변경할 수만 있고 읽을 수 없습니다.
외부 노출 범위를 세밀하게 제어하고 싶다면 목적에 맞게 골라 사용하면 됩니다.
여러 개의 인스턴스 변수 한 번에 정의하기
여러 개의 속성 메서드를 한꺼번에 정의하고 싶으신가요?
물론 가능합니다. 다만 올바른 문법을 사용해야 합니다.
다음과 같이 쉼표로 구분하면 됩니다:
attr_reader :name, :value, :ready?
원하는 만큼 몇 개든 추가할 수 있습니다.
정리
지금까지 루비의 속성 접근자에 대해 배웠습니다! attr_accessor, attr_writer, attr_reader 세 가지 메서드를 활용하면 클래스 외부에서 인스턴스 변수를 읽고 설정할 수 있습니다.
이제 직접 코드를 작성하며 연습해 볼 차례입니다.