Timex 이용 코드를 커맨드화하면 런타임 에러가 나온다 ~오마주~ (Elixir)

10439 단어 Elixir
(이 기사는 @piacerex 님의 Timex 사용 코드를 명령화하면 런타임 오류가 발생합니다.의 광고입니다)

이번에는 Timex을 사용하는 코드를 스크립트로 명령 할 때 런타임 오류가 발생하지 않도록하는 방법을 설명합니다.

escript에서의 커맨드 화에 대해서도 가볍게 설명합니다.

내 기사이지만 Slack Workflow의 신청 내용을 일람(CSV)으로 한다(with Elixir)
> elixir -v
Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Elixir 1.9.4 (compiled with Erlang/OTP 22)

escript로 Elixir 코드를 명령화



먼저 메인 모듈에 main() 함수를 추가합니다.

콘솔에서 호출하면 이 함수가 호출됩니다.

lib/sample.ex
defmodule Sample do
  def main(_args \\ []), do: IO.puts("Hello, world!")
end

mix.exs의 'def project' 아래에 escript 사용을 추가하고 'defp escript'에 메인 모듈의 모듈 이름을 추가합니다 (여기에서는 Elixir 프로젝트 이름을 'sample'로 지정합니다 ( > mix new sample )

mix.exs
defmodule Sample.MixProject do
  use Mix.Project

  def project do
    [
    
      escript: escript(), 
      deps: deps()
    ]
  end

  defp escript() do
    [main_module: Sample]
  end


escript로 명령화
> mix escript.build

콘솔에서의 실행은 다음과 같습니다.
> escript sample

Windows 이외의 경우 다음과 같이 실행할 수 있습니다.
% chmod 755 ./sample
% ./sample

Timex 사용 코드 명령어로 런타임 오류가 발생합니다.



Timex 모듈을 도입합니다.

mix.exs
defmodule Sample.Mixfile do
 …
  defp deps do
 …
    {:timex, "~> 3.6"}, 
 …
> mix deps.get

모처럼이므로 Timex을 사용합시다.

lib/sample.ex
defmodule Sample do
  def main(_args \\ []),
    do:
      Timex.now()
      |> Timex.local()
      |> Timex.format!("{YYYY}-{0M}-{0D} {h24}:{0m}:{0s}")
      |> IO.puts()
end

명령을 실행하면 다음 오류가 발생합니다.
> mix escript.build
> escript sample

13:41:51.198 [info]  Application tzdata exited: exited in: Tzdata.App.start(:normal, [])
    ** (EXIT) an exception was raised:
        ** (MatchError) no match of right hand side value: {:error, {:shutdown, {:failed_to_start_child, Tzdata.EtsHolder, {%ArgumentError{message: "unknown application: :tzdata"}, [{Application, :app_dir, 1, [file: 'lib/application.ex', line: 699]}, {Application, :app_dir, 2, [file: 'lib/application.ex', line: 726]}, {Tzdata.EtsHolder, :release_dir, 0, [file: 'lib/tzdata/ets_holder.ex', line: 123]}, {Tzdata.EtsHolder, :make_sure_a_release_dir_exists, 0, [file: 'lib/tzdata/ets_holder.ex', line: 101]}, {Tzdata.EtsHolder, :make_sure_a_release_is_on_file, 0, [file: 'lib/tzdata/ets_holder.ex', line: 77]}, {Tzdata.EtsHolder, :init, 1, [file: 'lib/tzdata/ets_holder.ex', line: 16]}, {:gen_server, :init_it, 2, [file: 'gen_server.erl', line: 374]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 342]}]}}}}
            (tzdata) lib/tzdata/tzdata_app.ex:17: Tzdata.App.start/2
            (kernel) application_master.erl:277: :application_master.start_it_old/4

이 문제를 해결하려면 tzdata 모듈에 .ets 파일의 위치를 ​​알려 둡니다.

( 여기Timex 에 따라 다름)
> iex -S mix
Erlang/OTP 22 [erts-10.5.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Interactive Elixir (1.9.4) - press Ctrl+C to exit (type h() ENTER for help)
iex> Tzdata.Util.data_dir
"c:/Users/torifuku/elixirProjects/sample/_build/dev/lib/tzdata/priv"
Tzdata.Util.data_dir 로 출력된 내용을 config/config.exs (이 파일이 없으면 만듭니다)로 설정합니다.

config/config.exs
use Mix.Config

config :tzdata,
       :data_dir,
       "c:/Users/torifuku/elixirProjects/sample/_build/dev/lib/tzdata/priv"


다시 빌드하고 실행하면 오류가 발생하지 않습니다
> mix escript.build
> escript sample
2020-01-12 15:58:19

일단 이것으로 해결할 수는 있지만 스마트하지 않으므로 더 좋은 방법이 있다면 댓글을 달 수있어서 기쁩니다.

보충


  • {:tzdata, "== 0.1.8", override: true}에서 버전을 고정하는 방법은 Elixir가 1.9.4라고 컴파일 오류가 발생했습니다.
    == Compilation error in file lib/tzdata/period_builder.ex ==
    ** (CompileError) lib/tzdata/period_builder.ex:60: undefined function from_standard_time_year/0
        (elixir) src/elixir_locals.erl:108: :elixir_locals."-ensure_no_undefined_local/3-lc$^0/1-0-"/2
        (elixir) src/elixir_locals.erl:109: anonymous fn/3 in :elixir_locals.ensure_no_undefined_local/3
        (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6
    could not compile dependency :tzdata, "mix compile" failed. You can recompile this dependency with "mix deps.compile tzdata", update it with "mix deps.update tzdata" or clean it with "mix deps.clean tzdata"
    
  • 참고하겠습니다 tzdata씨의 기사는 2016년의 어드벤트 캘린더입니다.
  • 그 전부터 Elixir에 주목받고 있었다는 것에 다시 한번 경의를 나타냅니다.
  • 좋은 웹페이지 즐겨찾기