1 minute read

{:poison, "~> 3.1"}

mix 빌드 툴에서 의존 라이브러리 버전을 기술하는데, 처음 보는 연산자가 있다. ~> 연산자는 뭐지?

| ~> 2.0.0     | >= 2.0.0 and < 2.1.0     |
| ~> 2.1.2     | >= 2.1.2 and < 2.2.0     |
| ~> 2.1.3-dev | >= 2.1.3-dev and < 2.2.0 |
| ~> 2.0       | >= 2.0.0 and < 3.0.0     |
| ~> 2.1       | >= 2.1.0 and < 3.0.0     |

# https://github.com/elixir-lang/elixir/blob/v1.6.4/lib/elixir/lib/version.ex
defmodule Version do
  defmodule Parser do
    defp approximate_upper(version) do
      case version do
        {major, _minor, nil, _} ->
          {major + 1, 0, 0, [0]}

        {major, minor, _patch, _} ->
          {major, minor + 1, 0, [0]}
      end

MAJOR.MINOR.PATCH 형식의 Semantic Versioning을 사용했을 때, 마이너(minor)나 패치(patch) 버전업만 허용한다. 패치 버전을 안 쓰면 마이너 버전업까지 허용한다. 반면 패치 버전을 쓰면 패치 버전업만 허용한다.

이건 다 Semantic Versioning 규칙 덕분이다. API 호환성을 유지한 채 기능 추가 버전을 허용한다면 ~> 3.1 적으면 되고 버그를 고친 버전업만 허용한다면 ~> 3.1.0 적으면 된다. 규칙이 있으니 이런 버전 업 규칙도 사용할 수 있다. 규칙 하나 잘 정하니 모두 행복해졌다.

~> 연산자를 비관적인 연산자(pessimistic operator)라 부르기도 한다. 왜 비관이란 단어가 들어가지? 낙관적인 버전 제약(optimistic version constraint)이 뭔지 알면 이해가 된다. >= 3.1 처럼 그냥 높으면 다 좋다는 식으로 적는 걸 낙관적이라고 한다. 상한선이 없는 낙관주의와 달리 상한선이 있기 때문에 비관적인 연산자라 부른다. 처음엔 뭔가 싶다가도 이해하니 그럴듯한 네이밍이다. upper가 들어간 네이밍 보다는 더 있어 보이는 것 같기도 하다.

물론 elixir 패키지 매니저에 처음 들어간 기능은 아니다. 찾아보진 않았지만, 루비 영향을 받지 않았을까 생각한다. 관련 자료도 가장 많이 나오더라.

참고