메서드와 인스턴스 변수

메서드와 인스턴스 변수 (Methods and instance variables)

메서드 파라미터를 인스턴스 변수에 할당하는 짧은 문법을 쓰면 생성자를 더 간단하게 만들 수 있어요:

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end
end

지금은 이름을 붙여서 사람을 만드는 것 외엔 별로 할 수 있는 게 없어요. 나이(age)는 항상 0이니까요. 그럼 사람을 나이 들게 만드는 메서드를 하나 추가해 볼게요:

class Person
  def initialize(@name : String)
    @age = 0
  end

  def age
    @age
  end

  def become_older
    @age += 1
  end
end

john = Person.new "John"
peter = Person.new "Peter"

john.age # => 0

john.become_older
john.age # => 1

peter.age # => 0

메서드 이름은 소문자로 시작하고, 관례상 소문자·언더스코어·숫자만 사용해요.

출처: Crystal 공식 문서

본문

게터와 세터 (Getters and setters)

Crystal 표준 라이브러리는 게터·세터 메서드 정의를 간단히 해주는 매크로를 제공해요:

class Person
  property age
  getter name : String

  def initialize(@name)
    @age = 0
  end
end

john = Person.new "John"
john.age = 32
john.age # => 32

게터·세터 매크로에 대한 자세한 내용은 표준 라이브러리 문서의 Object#getter, Object#setter, Object#property를 참고하세요.

참고로, become_older를 원래 Person 정의 안에 넣든, 별도의 정의에 넣든 상관없어요. Crystal은 모든 정의를 하나의 클래스로 합치니까요. 다음 코드는 전혀 문제없이 동작해요:

class Person
  def initialize(@name : String)
    @age = 0
  end
end

class Person
  def become_older
    @age += 1
  end
end

메서드 재정의와 previous_def (Redefining methods, and previous_def)

메서드를 재정의하면 마지막 정의가 우선해요.

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 2

previous_def로 이전에 정의된 메서드를 호출할 수 있어요:

class Person
  def become_older
    @age += 1
  end
end

class Person
  def become_older
    previous_def
    @age += 2
  end
end

person = Person.new "John"
person.become_older
person.age # => 3

인자나 괄호 없이 쓰면 previous_def는 메서드의 모든 파라미터를 인자로 받아요. 그렇지 않으면 넘겨주는 인자를 받아요.

통합 초기화 (Catch-all initialization)

인스턴스 변수는 initialize 메서드 바깥에서도 초기화할 수 있어요:

class Person
  @age = 0

  def initialize(@name : String)
  end
end

이렇게 하면 모든 생성자에서 @age를 0으로 초기화해요. 중복을 피하는 데도, 클래스를 다시 열어 인스턴스 변수를 추가할 때 Nil 타입이 붙는 것을 피하는 데도 유용해요.

더 알아보기

  • @name처럼 @로 시작하는 파라미터 문법은 생성자에서 인스턴스 변수 할당을 줄여줘요.
  • property, getter, setter 매크로로 게터·세터를 간단히 정의할 수 있어요.
  • 클래스를 열어 메서드를 재정의하면 마지막 정의가 우선하고, previous_def로 이전 정의를 호출할 수 있어요.
  • 인스턴스 변수는 initialize 밖에서도 초기화할 수 있어요.