LoginSignup
13
3

More than 1 year has passed since last update.

Timex利用コードをコマンド化すると実行時エラーが出る

Last updated at Posted at 2017-06-22

(この記事は Elixir (その2)とPhoenix Advent Calendar 2016 22日目の記事です)

今回は、Timexを使うコードを、escriptでコマンド化した際、実行時エラーが出るのを回避する方法を解説 :alarm_clock:

escriptでのコマンド化についても、軽く解説します

【2021/7/30追記】
この方法、下記最新ElixirおよびOTPバージョンでは使えないことを確認しました
escriptで日時周りを使いたい場合は、Timexの代わりにElixir標準モジュールのDateTimeやCalendar等をご利用ください

Erlang/OTP 24 [erts-12.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]

Elixir 1.12.0 (compiled with Erlang/OTP 24)

escriptでElixirコードをコマンド化

まず、メインモジュールにmain()関数を追加します

コンソールから呼び出したときは、この関数が呼ばれます

lib/sample.ex
defmodule Sample do
    def main( args \\ [] ) do

mix.exsの「def project」配下にescript利用を追記し、「def script」にメインモジュールのモジュール名を追加します(ここではElixirプロジェクト名を「sample」としています)

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

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

  def escript() do
    [ main_module: Sample ]
  end

escriptでコマンド化します

> mix escript.build

コンソールでの実行は、以下の通りです

> escript sample

Windows以外だと、以下でも実行できます

# chmod 755 ./sample
# ./sample

Timex利用コードのコマンド化で実行時エラーが出る

Timexmモジュールを導入します

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

コマンド化して実行すると、以下エラーが出ます

# mix escript.build
# escript sample
Could not start application tzdata: 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: 428]}, 
           {Application, :app_dir, 2, [file: 'lib/application.ex', line: 437]}, {Tzdata.EtsHolder, :release_dir, 0, [file: 'lib/tzdata/ets_holder.ex', line: 86]}, {Tzdata.EtsHolder, :make_sure_a_release_dir_exists, 0, [file: 'lib/tzdata/ets_holder.ex', line: 70]}, 
           {Tzdata.EtsHolder, :make_sure_a_release_is_on_file, 0, [file: 'lib/tzdata/ets_holder.ex', line: 64]}, {Tzdata.EtsHolder, :init, 1, [file: 'lib/tzdata/ets_holder.ex', line: 10]}, {:gen_server, :init_it, 6, [file: 'gen_server.erl', line: 328]},
           {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}}}
            (tzdata) lib/tzdata/tzdata_app.ex:15: Tzdata.App.start/2
            (kernel) application_master.erl:273: :application_master.start_it_old/4

これを回避するには、tzdataモジュールのバージョンを固定で指定します(元ネタはこちら

mix.exs
defmodule Sample.Mixfile do
 …
  defp deps do
 …
    { :tzdata, "== 0.1.8", override: true }, 
 …

ビルドし直して、実行すると、エラーが出なくなります :grinning:

# mix deps.get
# mix escript.build
# escript sample

p.s.OptionParseやコマンド終了ステータス等については、「Elixirでいい感じのCLIをパッと作ってサッと共有(できるようになる。そう、Elixir 1.3ならね)」が参考になります :art:


p.s.

6/17(土)の「第3回 ☆ データサイエンスLT&勉強会 ☆ in LINE福岡!」、60名を超える規模で盛り上がりました :angel_tone2:

image.png


7/28(金)、「Fukuoka CTO meetup」という福岡のCTOが集まってディスカッションするイベントで講演することになりました :airplane_small:

技術チームのマネジメントや、技術選定の基準となる考え方、地方でCTOとして働く理由、どのようにCTOになったのか等について、アレコレお話すると思います

image.png

13
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
3