Skip to main content

Command Palette

Search for a command to run...

Elixir 의 = 과 ^

Published
•2 min read•View as Markdown

엘릭서를 처음 배우면 = 때문에 헷갈리는 일이 있다.
다른 언어는 = 을 대입연산자라고 부른다.
하지만 엘릭서는 매칭연산자라고 부른다.


=는 패턴 매칭임

양쪽이 맞으면 변수에 값 바인딩 됨.

x = 1
# x == 1

{a, b} = {1, 2}
# a == 1, b == 2

즉, =는 “대입”이라기보다 양쪽 맞추기임.


매칭 실패도 있음

{a, b} = {1, 2, 3}
# MatchError

1 = 2
# MatchError

양쪽 안 맞으면 바로 MatchError 터짐.
즉, =는 검사 + 바인딩 같이 하는 특별한 연산자임.


변수는 재바인딩 가능

문제는 이미 값 있는 변수도 다시 바인딩됨.

x = 1
x = 2
# x == 2

{x, y} = {3, 4}
# x == 3, y == 4

엘릭서 변수는 기본적으로 재바인딩 허용.
유연하긴 한데, 의도 헷갈릴 때 많음.


그래서 ^ 필요함

“이 값 그대로여야 한다” 강제하고 싶으면 핀 연산자(^) 씀.

x = 1

{^x, y} = {1, 2}
# 성공. y == 2

{^x, y} = {2, 3}
# MatchError. x는 1이어야 함

핀은 변수 값 고정시켜놓고 매칭 돌림.
즉, 재바인딩 막고 값 고정 기능임.


예제 모음

1. case에서

user_id = 42

case {:ok, 42} do
  {:ok, ^user_id} -> :same_user
  {:ok, _}        -> :different_user
end
# :same_user

핀 없으면 첫 절이 항상 실행됨. 버그 소스 됨.


2. 함수 인자에서

def update(^id, %{id: id} = rec, params), do: apply_changes(rec, params)
def update(_, rec, _), do: {:error, :id_mismatch}

API나 DB에서 ID 반드시 같아야 하는 상황 → 핀으로 바로 표현 가능.


3. 맵/바이너리

%{type: ^expected} = %{type: "image/png", size: 200}
# 매치 성공

<< "image/", ^subtype :: binary >> = "image/png"
# subtype == "png"

데이터 구조 분해하면서 값 고정 가능.
프로토콜 파싱이나 검증에 유용함.


언제 쓰지 말까

  • 모든 검증을 ^로 때려넣으면 가독성 박살남

  • 값이 바뀌는 게 핵심인 코드에 쓰면 유지보수 지옥됨

👉 진짜 “이 값이어야만 한다” 규칙 있을 때만 쓰는 게 정석임.


실무에서 가치

  • API 요청 검증: URL 파라미터 ID랑 바디 ID 같아야 함

  • GenServer 상태 전이: 특정 상태일 때만 이벤트 허용

  • DB 무결성: 참조 일치 여부 확인

핀 쓰면 if문보다 자연스럽고, 의도 코드에 바로 드러남.


한 줄 요약

엘릭서에서 =은 대입 아님. 패턴 매칭임.
그리고 ^는 변수 고정해서 “이 값이어야 한다” 명시하는 도구임.

More from this blog

Ash Typescript

TL;DRElixir의 Ash Framework로 정의한 리소스를 TypeScript와 바로 연결해 주는 툴.백엔드 스펙을 따로 문서화하지 않아도 타입 안정성과 동기화를 자동으로 보장한다. 왜 사용하는가? Elixir로 백엔드를, TypeScript로 프런트엔드를 작성하다 보면 변경되는 API 스펙을 항상 동기화된 상태로 관리하기 쉽지 않다.결국 동기화를 위해서는 Graphql 을 사용하거나, 별도의 툴이 필요하다.AshTypescript ...

Sep 28, 20253 min read

Ash Reactor

TLDR; Reactor는 복잡한 워크플로우를 단계별로 정의하고 실행하는 라이브러리다. 각 단계가 독립적으로 돌아가며, 병렬 처리와 에러 핸들링도 쉽게 할 수 있다. 왜 쓸까? 프로젝트에서 "데이터 조회 → 가공 → 외부 API 호출 → 저장" 같은 복잡한 로직을 처리할 때가 있다.이런걸 그냥 함수로 쭉 연결하면 코드가 복잡해지고 에러 처리도 어려워진다. Reactor를 쓰면 각 단계를 명확히 분리하고 선언적으로 워크플로우를 관리할 수 있다. ...

Sep 21, 20254 min read

Ash StateMachine

TLDR; Ash StateMachine 은 상태 변경이 가능한 케이스를 명시하고, 미리 선언된 상태 변경만 가능하도록 한다. 왜 쓸까? 예를 들면, “새로 생성 → 진행 중 → 완료” 처럼 정해진 workflow 가 있다면, 로직으로 if/else 를 사용하는 것보다 상태머신으로 선언해 두는 게 안전하고 읽기 쉽다. 예제: Task 요구사항: 기본 상태는 :new :start 액션이 :new → :in_progress :finish ...

Sep 14, 20252 min read

Ash Oban

최근 작업중에 이메일 발송을 처리해야 했다.after_action 에 이마일 발송을 고려했는데 최종적으로는 AshOban 을 사용했다. AshOban이 뭔가? Ash Framework와 Oban을 이어주는 라이브러리다. 백그라운드 job을 Ash 스타일로 쓸 수 있게 해준다. 멤버 초대 이메일 보내기 클럽에 새 멤버를 초대하면 이메일을 보내야 하는 상황이다. 이걸 어떻게 처리할까? Action Hook으로 하면: 사용자가 서버에서 이메일 발송...

Aug 31, 20252 min read

kkbz.hop

14 posts