모듈

모듈 에서 Crystal

1개의 연습 문제

모듈 소개

Crystal의 모듈은 두 가지 목적으로 사용해요.

첫 번째 목적은 이름 충돌을 피하기 위해 네임스페이스를 만드는 거예요. 또한 코드를 묶어 주기 때문에, 그 코드가 무엇을 위한 것인지 더 쉽게 이해할 수 있게 해줘요.

두 번째 목적은 타입끼리 코드를 공유하기 위한 믹스인을 정의하는 거예요.

모듈은 클래스와 비슷하지만, 가장 큰 차이는 인스턴스를 만들 수 없다는 점이에요. 그래서 인스턴스 변수도 없어요.

모듈을 선언하려면 module 키워드 뒤에 모듈 이름을 써요.

module Foo
end

네임스페이스

네임스페이스는 코드를 묶는 방법이에요. 이름 충돌을 피하고, 그 코드가 무엇을 위한 것인지 더 쉽게 이해할 수 있게 해줘요. 네임스페이스 안에 넣어 둔 상수나 클래스에 접근하고 싶을 때는 :: 연산자를 사용해요.

module Foo
  class Bar
  end
end

Foo::Bar.new

믹스인으로 사용하기

예를 들어 여러 클래스가 같은 "기본" 기능을 필요로 하거나, 서로 관련 없는 클래스끼리 코드를 공유해야 할 때 유용해요. 관련 없는 클래스 사이에서 코드를 공유하고 싶을 때도 마찬가지예요.

모듈을 믹스인으로 사용하는 방법에는 두 가지가 있어요. 첫 번째는 include 키워드를 사용하는 것이고, 두 번째는 extend 키워드를 사용하는 것이에요.

두 방법 모두 모듈을 include하거나 extend한 타입에서 상수를 사용할 수 있게 해줘요.

include

include를 사용하면 모듈의 모든 메서드를, 모듈을 include한 타입의 인스턴스 메서드로 사용할 수 있어요. include 키워드는 타입의 맨 위에 쓰고, 뒤에 모듈 이름을 적어요.

module Foo
  def foo
    "foo"
  end
end

class Bar
  include Foo
end

Bar.new.foo # => "foo"

extend

extend는 include와 비슷하게 동작하지만, 메서드를 인스턴스 메서드로 사용할 수 있게 하는 대신 클래스 메서드로 사용할 수 있게 해요. extend 키워드도 타입의 맨 위에 쓰고, 뒤에 모듈 이름을 적어요.

module Foo
  def foo
    "foo"
  end
end

class Bar
  extend Foo
end

Bar.foo # => "foo"

extend self

Crystal에서 흔히 쓰는 패턴 중 하나는 모듈에서 extend self 패턴을 사용하는 거예요. 이렇게 하면 모듈의 모든 메서드를 모듈 자체의 클래스 메서드로 사용할 수 있어요. 즉, def self.method_name 문법으로 각 메서드를 모듈에 일일이 할당할 필요가 없어요.

module Foo
  extend self

  def foo
    "foo"
  end
end

Foo.foo # => "foo"
GitHub에서 편집 링크가 새 창이나 탭에서 열려요

모듈 배우기

연습이 잠겨 있어요

모듈 개념을 연습하려면 연습 문제 2개를 더 잠금 해제해요