Elixir-매크로
매크로는 Elixir의 가장 진보되고 강력한 기능 중 하나입니다. 모든 언어의 모든 고급 기능과 마찬가지로 매크로는 드물게 사용되어야합니다. 컴파일 시간에 강력한 코드 변환을 수행 할 수 있습니다. 이제 매크로가 무엇이며 매크로를 사용하는 방법을 간략하게 이해합니다.
인용문
매크로에 대해 이야기하기 전에 먼저 Elixir 내부를 살펴 보겠습니다. Elixir 프로그램은 자체 데이터 구조로 나타낼 수 있습니다. Elixir 프로그램의 빌딩 블록은 세 가지 요소가있는 튜플입니다. 예를 들어 함수 호출 sum (1, 2, 3)은 내부적으로 −
{:sum, [], [1, 2, 3]}
첫 번째 요소는 함수 이름이고 두 번째 요소는 메타 데이터를 포함하는 키워드 목록이며 세 번째 요소는 인수 목록입니다. 다음을 작성하면 iex 셸의 출력으로 얻을 수 있습니다.
quote do: sum(1, 2, 3)
연산자도 그러한 튜플로 표시됩니다. 변수는 또한 마지막 요소가 목록이 아니라 원 자라는 점을 제외하고는 이러한 세 가지 요소를 사용하여 표현됩니다. 더 복잡한 표현식을 인용 할 때 코드가 이러한 튜플에 표현되어 있음을 알 수 있습니다. 이러한 튜플은 종종 트리와 유사한 구조로 서로 중첩됩니다. 많은 언어는 이러한 표현을Abstract Syntax Tree (AST). Elixir는 이러한 인용 된 표현을 호출합니다.
인용 해제
이제 코드의 내부 구조를 검색 할 수 있습니다. 어떻게 수정합니까? 새로운 코드 또는 값을 주입하기 위해unquote. 표현식을 인용 해제하면 평가되고 AST에 삽입됩니다. 개념을 이해하기 위해 예제 (iex 셸)를 고려해 보겠습니다.
num = 25
quote do: sum(15, num)
quote do: sum(15, unquote(num))
위의 프로그램이 실행되면 다음과 같은 결과가 생성됩니다.
{:sum, [], [15, {:num, [], Elixir}]}
{:sum, [], [15, 25]}
따옴표 표현식의 예에서는 num을 25로 자동 대체하지 않았습니다. AST를 수정하려면이 변수의 따옴표를 해제해야합니다.
매크로
이제 인용 및 인용 해제에 익숙해 졌으므로 매크로를 사용하여 Elixir에서 메타 프로그래밍을 탐색 할 수 있습니다.
가장 간단한 용어로 매크로는 애플리케이션 코드에 삽입 될 따옴표로 묶인 식을 반환하도록 설계된 특수 함수입니다. 매크로가 함수처럼 호출되지 않고 인용 된 표현식으로 대체되는 것을 상상해보십시오. 매크로를 사용하면 Elixir를 확장하고 애플리케이션에 코드를 동적으로 추가하는 데 필요한 모든 것이 있습니다.
매크로가 아닌 이상 구현합시다. 다음을 사용하여 매크로를 정의하는 것으로 시작합니다.defmacro매크로. 매크로는 인용 된 표현식을 반환해야합니다.
defmodule OurMacro do
defmacro unless(expr, do: block) do
quote do
if !unquote(expr), do: unquote(block)
end
end
end
require OurMacro
OurMacro.unless true, do: IO.puts "True Expression"
OurMacro.unless false, do: IO.puts "False expression"
위의 프로그램이 실행되면 다음과 같은 결과가 생성됩니다.
False expression
여기에서 일어나고있는 것은 우리의 코드에 의해 반환 된 인용 코드에 의해 대체되고있다 않는 매크로입니다. 현재 컨텍스트에서 평가하기 위해 표현식을 인용 해제하고 해당 컨텍스트에서 실행하기 위해 do 블록을 인용 해제했습니다. 이 예는 elixir에서 매크로를 사용한 메타 프로그래밍을 보여줍니다.
매크로는 훨씬 더 복잡한 작업에 사용할 수 있지만 드물게 사용해야합니다. 일반적으로 메타 프로그래밍은 나쁜 습관으로 간주되며 필요한 경우에만 사용해야하기 때문입니다.