모듈
모듈 (Modules)
에를랭 코드는 _모듈(module)_로 나뉘어요. 모듈은 속성(attribute)들과 함수 선언의 연속으로 이루어지며, 각각은 마침표(.)로 끝납니다.
예시:
-module(m). % module attribute
-export([fact/1]). % module attribute
fact(N) when N>0 -> % beginning of function declaration
N * fact(N-1); % |
fact(0) -> % |
1. % end of function declaration
함수 선언에 대한 설명은 Function Declaration Syntax를 참고하세요.
모듈 속성 (Module Attributes)
_모듈 속성(module attribute)_은 모듈의 특정 속성을 정의해요.
모듈 속성은 태그(tag)와 값(value)으로 이루어집니다:
-Tag(Value).
Tag는 반드시 원자(atom)여야 하고, Value는 반드시 리터럴 용어(literal term)여야 해요. 사용자 정의 속성에서 편의상, 리터럴 용어 Value가 Name/Arity 문법(여기서 Name은 원자, Arity는 양의 정수)이면 그 Name/Arity 용어는 {Name,Arity}로 변환됩니다.
모든 모듈 속성을 지정할 수 있어요. 속성들은 컴파일된 코드에 저장되며 Module:module_info(attributes)를 호출하거나 STDLIB의 beam_lib 모듈을 사용해서 얻을 수 있습니다.
여러 모듈 속성은 미리 정의된 의미를 가집니다. 그중 일부는 arity가 2인데, 사용자 정의 모듈 속성은 반드시 arity가 1이어야 해요.
미리 정의된 모듈 속성 (Pre-Defined Module Attributes)
미리 정의된 모듈 속성은 어떤 함수 선언보다 앞에 놓여야 합니다.
-
-module(Module).- 모듈 선언. 모듈의 이름을 정의해요. 원자인 이름Module은 확장자.erl을 뺀 파일 이름과 같아야 합니다. 그렇지 않으면 코드 로딩이 의도대로 동작하지 않아요.이 속성은 첫 번째로 지정되어야 하며 유일하게 필수인 속성입니다.
-
-export(Functions).- 내보내는(export) 함수. 모듈 안에 정의된 함수들 중 어느 것이 모듈 밖에서 보이는지를 지정해요.Functions는 리스트[Name1/Arity1, ..., NameN/ArityN]이며, 각NameI는 원자,ArityI는 정수입니다. -
-import(Module, Functions).- 가져오는(import) 함수. 로컬 함수와 같은 방식으로, 즉 모듈 접두어 없이 호출할 수 있어요.원자인
Module은 어느 모듈에서 함수를 가져올지 지정합니다.Functions는export와 비슷한 리스트예요. -
-moduledoc(Documentation).또는-moduledoc Documentation.- 이 모듈에 대한 사용자 문서.Documentation에 허용되는 값은-doc와 동일합니다.-moduledoc사용법에 대한 자세한 내용은 Documentation을 참고하세요. -
-compile(Options).- 컴파일러 옵션.Options는 단일 옵션 또는 옵션 리스트예요. 이 속성은 모듈을 컴파일할 때 옵션 목록에 추가됩니다. Compiler의m:compile모듈을 참고하세요. -
-vsn(Vsn).- 모듈 버전.Vsn은 아무 리터럴 용어나 될 수 있고beam_lib:version/1로 얻을 수 있어요.이 속성을 지정하지 않으면 버전은 모듈의 MD5 체크섬으로 기본 설정됩니다.
-
-on_load(Function).- 이 속성은 모듈이 로드될 때 자동으로 실행될 함수를 지정해요. 자세한 내용은 Running a Function When a Module is Loaded를 참고하세요. -
-nifs(Functions).- 모듈 안에 정의된 함수들 중 어떤 것들이erlang:load_nif/2로 NIF로 로드될 수 있는지를 지정해요.Functions는 리스트[Name1/Arity1, ..., NameN/ArityN]이며, 각NameI는 원자,ArityI는 정수입니다.엄밀히 필수는 아니지만, NIF를 로드하는 모듈에서는
-nifs()속성을 사용하는 걸 권장합니다. 컴파일러가 최적화에 대해 더 나은 결정을 내릴 수 있게 되거든요.NIF를 로드하지 않는 모듈에는
-nifs([])를 추가할 필요가 없어요. 모듈 안에erlang:load_nif/2호출이 하나도 없다는 사실만으로도 컴파일러는 같은 결론을 내리기에 충분합니다.Change {: .info }
-nifs()속성의 특별한 의미는 Erlang/OTP 25.0에서 도입됐어요. 그 이전 릴리스에서-nifs()는 받아들여지긴 했지만 특별한 의미가 없었습니다.
Behaviour 모듈 속성 (Behaviour Module Attribute)
모듈이 behaviour 의 콜백 모듈임을 지정할 수 있어요:
-behaviour(Behaviour).
원자 Behaviour는 behaviour의 이름을 주며, 사용자 정의 behaviour일 수도 있고 다음 OTP 표준 behaviour 중 하나일 수도 있어요:
gen_servergen_statemgen_eventsupervisor
철자 behavior도 허용됩니다.
모듈의 콜백 함수는 내보내진 함수 behaviour_info/1로 직접 지정할 수도 있고:
behaviour_info(callbacks) -> Callbacks.
각 콜백 함수에 대해 -callback 속성으로 지정할 수도 있어요:
-callback Name(Arguments) -> Result.
여기서 Arguments는 0개 이상의 인자 리스트예요. -callback 속성이 더 선호되는데, 추가 타입 정보를 도구가 문서 생성이나 불일치 발견에 사용할 수 있기 때문입니다.
behaviour와 콜백 모듈에 대해 더 알아보려면 OTP Design Principles를 읽어보세요.
레코드 정의 (Record Definitions)
레코드 정의에는 모듈 속성과 비슷한 문법을 사용합니다:
-record(Record, Fields).
레코드 정의는 함수 선언 사이를 포함해 모듈 어디에도 둘 수 있어요. 자세한 내용은 Records를 참고하세요.
네이티브 레코드 정의 (Native Record Definitions)
네이티브 레코드 정의에는 모듈 속성과 비슷한 문법을 사용해요:
-record #Record{Field1, Field2, ..., FieldN}.
레코드 정의는 함수 선언 사이를 포함해 모듈 어디에도 둘 수 있습니다. 자세한 내용은 Native Records를 참고하세요.
전처리기 (Preprocessor)
전처리기는 파일 포함, 매크로, 조건부 컴파일을 지원하며 모듈 속성과 같은 문법을 사용합니다:
-include("SomeFile.hrl").
-define(Macro, Replacement).
자세한 내용은 Preprocessor를 참고하세요.
파일과 줄 설정 (Setting File and Line)
미리 정의된 매크로 ?FILE과 ?LINE을 변경하는 데 모듈 속성과 같은 문법을 사용해요:
-file(File, Line).
이 속성은 Yecc 같은 도구가 소스 프로그램이 다른 도구에 의해 생성됐다는 것을 컴파일러에 알릴 때 사용합니다. 또한 소스 프로그램이 만들어지게 된 원래 사용자 작성 파일의 줄과 소스 파일의 대응 관계를 나타내요.
타입과 함수 스펙 (Types and function specifications)
타입과 함수 스펙을 지정하는 데 모듈 속성과 비슷한 문법을 씁니다:
-type my_type() :: atom() | integer().
-spec my_function(integer()) -> integer().
자세한 내용은 Types and Function specifications를 참고하세요.
이 설명은 EEP8 - Types and function specifications에 기반하며, 그 문서는 더 이상 갱신되지 않습니다.
문서 속성 (Documentation attributes)
모듈 속성 -doc(Documentation)는 함수/타입/콜백에 사용자 문서를 제공하는 데 사용됩니다:
-doc("Example documentation").
example() -> ok.
이 속성은 문서화하는 대상 바로 앞에 놓아야 해요. Documentation 주변의 괄호는 선택적입니다. Documentation에 허용되는 값은 다음과 같아요:
-
리터럴 문자열 또는 UTF-8로 인코딩된 바이너리 문자열 - 대상을 문서화하는 문자열. 리터럴 문자열이면 무엇이든 허용되므로, 삼중 따옴표 문자열이나 리터럴 문자열로 변환되는 시길(sigil)도 쓸 수 있어요. 다음 예시들은 모두 동등합니다:
-doc("Example \"docs\""). -doc(<<"Example \"docs\""/utf8>>). -doc ~S/Example "docs"/. -doc """ Example "docs" """ -doc ~B|Example "docs"|.명확성을 위해 문서 속성에는 일반
"strings"또는 삼중 따옴표 문자열을 쓰는 게 권장됩니다. -
{file,t:file:name/0}- 파일 이름의 내용을 읽어 그 내용을 문서 문자열로 사용합니다. -
false- 현재 대상을 숨김으로 설정합니다. 즉, 사용 가능한 함수로 나열되지 않으며 문서도 없어요. -
Metadata ::map()- 현재 대상에 대한 메타데이터. 메타데이터의 일부 키는 특별한 의미를 가집니다. 자세한 내용은 Moduledoc metadata와 Doc metadata를 참고하세요.
대상당 여러 Metadata 문서 속성을 가질 수 있지만, 문서 문자열 항목은 하나만 허용됩니다.
자세한 내용은 Erlang Reference Manual의 Documentation 가이드를 참고하세요.
feature 지시어 (The feature directive)
모듈 속성은 아니지만 지시어(directive)로서(문법에 영향을 줄 수 있으므로) feature를 활성화·비활성화하는 -feature(..) 지시어가 있습니다.
문법은 속성과 비슷하지만 인자가 두 개예요:
-feature(FeatureName, enable | disable).
feature 지시어는 모듈의 접두부(prefix)에만 나타날 수 있음에 주의하세요.
주석 (Comments)
주석은 문자열과 따옴표로 감싼 원자 안을 제외하고 모듈 어디에나 둘 수 있어요. 주석은 % 문자로 시작해 다음 줄 끝 직전까지 계속됩니다. 주석은 효과가 없으며 본질적으로 공백과 동등해요.
module_info/0 및 module_info/1 함수
컴파일러는 각 모듈에 두 개의 특별하고 내보내진 함수를 자동으로 삽입합니다:
Module:module_info/0Module:module_info/1
이 함수들이 호출되면 모듈에 대한 정보를 얻을 수 있어요.
module_info/0
각 모듈의 module_info/0 함수는 모듈에 대한 정보가 담긴 {Key,Value} 튜플 리스트를 반환합니다. 이 글을 쓰는 시점에 그 리스트는 다음 Key들을 가진 튜플을 포함해요: module, attributes, compile, exports, md5. 튜플의 순서와 개수는 사전 통지 없이 바뀔 수 있습니다.
module_info/1
호출 module_info(Key)에서 Key는 원자로, 모듈에 대한 단일 정보를 반환해요.
Key에 허용되는 값은 다음과 같습니다:
-
module- 모듈 이름을 나타내는 원자를 반환합니다. -
attributes-{AttributeName,ValueList}튜플 리스트를 반환합니다.AttributeName은 속성 이름이고,ValueList는 값 리스트예요. 주의: 속성이 모듈 안에 두 번 이상 나타나면, 그 속성은 서로 다른 값으로 리스트에 두 번 이상 나타날 수 있습니다.모듈을
beam_lib:strip/1로 스트립하면 속성 리스트는 비어집니다. -
compile- 모듈이 어떻게 컴파일됐는지에 대한 정보를 담은 튜플 리스트를 반환합니다. 모듈이beam_lib:strip/1로 스트립되면 이 리스트는 비어요. -
md5- 모듈의 MD5 체크섬을 나타내는 바이너리를 반환합니다. -
exports- 모듈의 모든 내보내진 함수가 담긴{Name,Arity}튜플 리스트를 반환합니다. -
functions- 모듈의 모든 함수가 담긴{Name,Arity}튜플 리스트를 반환합니다. -
nifs- 모듈의 모든 NIF 함수가 담긴{Name,Arity}튜플 리스트를 반환합니다.