Use Livebook to open this notebook and explore new ideas.
It is easy to get started, on your machine or the cloud.
%{
title: "Elixir v1.14 is released - dbg",
description: "디버깅을 하는 가장 우아한 방법",
category: :dev,
cover_url: "https://opengraph.githubassets.com/d7811f58d3c80b5881c265bd02999a35433efeb8e348ac3db92bb3f573709723/elixir-lang/elixir/commit/c5151e6890b5ac8df13276459696f0f47a8e634b"
}
---
<!-- livebook:{"persist_outputs":true} -->
## Elixir v1.14
이 문서는 Livebook 으로 작성되었습니다.
<!-- livebook:{"break_markdown":true} -->
Elixir v1.14 가 출시되었다! [1](https://elixir-lang.org/blog/2022/09/01/elixir-v1-14-0-released/)
한동안 그래왔듯 이번 버전에서는 DX(Developer eXperience), 특히 디버깅과 관련된 발전에 집중했다고 한다.
"한동안 DX 에 집중해왔다니? 언어 발전은 없고 이거 망해가는 것 아닌가요?" 라고 생각할 수도 있겠지만, **Elixir 는 v1.9 에서 이미 마지막으로 예정되어있던 기능인 Releases 를 완성했다**.
> Releases was the last planned feature for Elixir. We don’t have any major user-facing feature in the works nor planned.
>
> \- José Valim [2](https://elixir-lang.org/blog/2019/06/24/elixir-v1-9-0-released/)
그래서 이후로 6개월 마다 주기적으로 자잘한 개선과 버그 수정이 주가되어 새로운 버전이 출시되고 있다.
이번 글에서는 Elixir v1.14 의 가장 중요한 개선인 `dbg` 를 살펴본다.
## dbg
Elixir 를 사용한다면 아마 디버깅을 위해 [`IO.inspect/2`](https://github.com/elixir-lang/elixir/blob/v1.14.0/lib/elixir/lib/io.ex#L452) 를 자주 사용해 왔을 것이다. [`Kernel.dbg/2`](https://github.com/elixir-lang/elixir/blob/v1.14.0/lib/elixir/lib/kernel.ex#L5851) 는 디버깅을 위해 특화된 기능을 제공하여 `IO.inspect/2` 를 대체할 것으로 생각된다.
<!-- livebook:{"break_markdown":true} -->
### Debugging with `IO.inspect/2`
`IO.inspect/2` 는 인자의 값을 보기 좋게 출력하고 해당 값을 그대로 반환한다. 그래서 디버깅 할 때 자주 쓰이는데, 여기저기 쓸 때는 어느 인자의 값을 보여줬는지 알 수 없어서 `:label` option 을 사용해야 했다.
```elixir
fun = fn str ->
str
|> String.trim_trailing("!")
|> IO.inspect(label: 1)
|> String.split()
|> IO.inspect(label: 2)
|> List.first()
|> IO.inspect(label: 3)
end
fun.("Elixir is cool!")
```
<!-- livebook:{"output":true} -->
```
1: "Elixir is cool"
2: ["Elixir", "is", "cool"]
3: "Elixir"
```
<!-- livebook:{"output":true} -->
```
"Elixir"
```
### Debugging with `Kernel.dbg/2`
`Kernel.dbg/2` 는 크게 두 가지로 사용법이 나뉜다. 먼저 arguments 없이 사용하면 해당 위치에서의 binding 을 출력한다.
```elixir
fun = fn str ->
dbg()
str
|> String.trim_trailing("!")
|> String.split()
|> List.first()
end
fun.("Elixir is cool!")
```
<!-- livebook:{"output":true} -->
```
[/Users/json/workspace/project/json/json_corp/apps/json_corp/priv/posts/20220918_elixir_1_14.livemd#cell:2: (file)]
binding() #=> [fun: #Function<42.3316493/1 in :erl_eval.expr/6>, str: "Elixir is cool!"]
```
<!-- livebook:{"output":true} -->
```
"Elixir"
```
`fun/1` 이 호출되었을 때 binding 되어있는 `fun`, `str` 을 출력하는 것을 확인할 수 있다.
<!-- livebook:{"break_markdown":true} -->
`Kernel.dbg/2` 를 arguments(code pipeline) 와 함께 사용하면, 코드를 분성하여 매 단계 마다의 디버깅 정보를 출력한다.
```elixir
fun = fn str ->
str
|> String.trim_trailing("!")
|> String.split()
|> List.first()
|> dbg()
end
fun.("Elixir is cool!")
```
<!-- livebook:{"output":true} -->
```
[/Users/json/workspace/project/json/json_corp/apps/json_corp/priv/posts/20220918_elixir_1_14.livemd#cell:6: (file)]
str #=> "Elixir is cool!"
|> String.trim_trailing("!") #=> "Elixir is cool"
|> String.split() #=> ["Elixir", "is", "cool"]
|> List.first() #=> "Elixir"
```
<!-- livebook:{"output":true} -->
```
"Elixir"
```
`|> String.trim_trailing("!") #=> "Elixir is cool"` 와 같이 pipeline 의 각 코드와 그 결과가 모두 출력되기 때문에 디버깅 하기가 매우 수월하다.
<!-- livebook:{"break_markdown":true} -->
### IEx + dbg
`dbg` 는 backend 를 설정가능하다. 이 의미는 `Kernel.dbg/2` 로 전달되는 정보를 가지고 원하는 대로 동작을 구성할 수 있다는 것이다. 참고로 위에서 본 것은 default backend 인 [`Macro.dbg/3`](https://github.com/elixir-lang/elixir/blob/v1.14.0/lib/elixir/lib/macro.ex#L2424) 의 동작이다.
IEx 에서는 `dbg` 에 자체적인 backend 로 코드를 단계별로 실행하며 디버깅 할 수 있는 prying 기능을 지원한다.
[Elixir's new "dbg" with IEx breakpoints on pipes](https://asciinema.org/a/509509)
<script id="asciicast-509509" src="https://asciinema.org/a/509509.js" async></script>
<!-- livebook:{"break_markdown":true} -->
### Livebook + dbg
[`Livebook`](https://livebook.dev/) 에서도 [`kino`](https://github.com/livebook-dev/kino) 의 custom backend 를 이용해 interactive 하게 디버깅 할 수 있는 기능이 [추가될 예정](https://github.com/livebook-dev/kino/pull/191)이다.
<video src="https://user-images.githubusercontent.com/17034772/187455667-b166ce50-c440-444c-94dc-e2c0280a4924.webm" controls="controls" muted="muted" style="max-height:640px;">
</video>
<!-- livebook:{"break_markdown":true} -->
다음에는 이어서 Elixir v1.14 에 추가된 `PartitionSupervisor` 에 대해 다뤄보겠다.
See source