/var/log/messages

Feb 21, 2019 - 4 minute read - Comments - programming

Metaprogramming Elixir (10)

Code Generation from Remote APIs という題が付いています。これは凄い。

Mix Project Setup

テキストのソレは version が微妙なのかしら。

$ mix new hub --bare
** (Mix) Could not invoke task "new": 1 error found!
--bare : Unknown option

とりあえず mix new で云々してみます。

$ mix new hub
* creating README.md
* creating .formatter.exs
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/hub.ex
* creating test
* creating test/test_helper.exs
* creating test/hub_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd hub
    mix test

Run "mix help" for more commands.
$ cd hub

で、mix.exs を云々する模様。確認してみるに

defmodule Hub.MixProject do
  use Mix.Project

  def project do
    [
      app: :hub,
      version: "0.1.0",
      elixir: "~> 1.7",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

てなってて、テキストの elixir は "~> 1.0.0" てなってますね。以下の部分を修正して

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"},
      {:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.0"},
      {:poison, "~> 1.3.0"},
      {:httpotion, "~> 1.0.0"}
    ]
  end

以下を実行。

$ mix deps.get
* Getting ibrowse (https://github.com/cmullaparthi/ibrowse.git)
remote: Enumerating objects: 1493, done.        
remote: Total 1493 (delta 0), reused 0 (delta 0), pack-reused 1493        
Receiving objects: 100% (1493/1493), 918.96 KiB | 894.00 KiB/s, done.
Resolving deltas: 100% (950/950), done.
Resolving Hex dependencies...
Dependency resolution completed:
New:
  httpotion 1.0.0
  poison 1.3.1
* Getting poison (Hex package)
* Getting httpotion (Hex package)

これで準備完了な模様?

Remote Code Generation

以下、機械翻訳を列挙しておきます。

  • メインの hub.ex モジュールを開き、リモート API からコードを生成
  • GitHub のパブリック API にアクセスして GitHub のユーザー名の下にあるすべてのリポジトリを取得し、JSON 本体を Elixir マップにデコード
  • 次に、各結果から、関数名がリポジトリの名前で、関数本体が各 GitHub プロジェクトに関するすべてのデータである関数を定義
  • 最後に、リポジトリの名前を受け取り、そのURLに対してWebブラウザを起動するgo関数を定義

え、go ですって。。。

hub/lib/hub.ex

以下な模様。

defmodule Hub do
  @moduledoc """
  Documentation for Hub.
  """

  @doc """
  Hello world.

  ## Examples

      iex> Hub.hello()
      :world

  """
  Httpotion.start
  @username "yamanetoshi"

  "https://api.github.com/users/#{@usernae}/repos"
  |> HTTPotion.get(["UserAgent": "Elixir"])
  |> Map.get(:body)
  |> Poison.decode!
  |> Enum.each fn repo ->
      def unquote(String.to_atom(repo["name"]))() do
        unquote(Macro.escape(repo))
        end
      end

      def go(repo) do
        url = apply(__MODULE__, repo, [])["html_url"]
        IO.puts "Launching browser to #{url}..."
        System.cmd("open", [url])
      end
end

とりあえず

$ iex -S mix

できません。

$ iex -S mix
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

===> Compiling ibrowse
===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

言われた通りにやってみます。

$ mix deps.compile ibrowse
===> Compiling ibrowse
===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

駄目だな。あるいは以下?

$ mix deps.clean ibrowse
* Cleaning ibrowse
$ mix deps.update ibrowse
* Getting ibrowse (https://github.com/cmullaparthi/ibrowse.git)
remote: Enumerating objects: 1493, done.        
remote: Total 1493 (delta 0), reused 0 (delta 0), pack-reused 1493        
Receiving objects: 100% (1493/1493), 918.96 KiB | 1.21 MiB/s, done.
Resolving deltas: 100% (950/950), done.
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
  httpotion 1.0.0
  poison 1.3.1

これでリトライしましたが

$ iex -S mix
Erlang/OTP 21 [erts-10.1] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe] [dtrace]

===> Compiling ibrowse
===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

駄目ですね。よく出力を見てみます。とりあえず以下が失敗しています。

$ mix deps.compile ibrowse
===> Compiling ibrowse
===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

ヨシ

      {:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.4"},

でコンパイル通った。

$ mix deps.compile ibrowse
===> Compiling ibrowse

がしかし、他のが駄目。

$ iex -S mix

(中略)

** (UndefinedFunctionError) function Httpotion.start/0 is undefined (module Httpotion is not available)

ぐぬぬ。

その後

  Ensure they match or specify one of the above in your deps and set "override: true"

てことなのでこうして

      {:ibrowse, github: "cmullaparthi/ibrowse", override: true},

なんとかなったのかどうか。。。

$ mix deps.get
* Updating ibrowse (https://github.com/cmullaparthi/ibrowse.git)
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
  httpotion 3.1.1
  poison 1.3.1

まだ駄目みたい。

$ iex -S mix

(中略)

Ambiguous pipe found at:
  lib/hub.ex:22


22:02:08.524 [error] beam/beam_load.c(1428): Error loading module 'Elixir.Httpotion':
  module name in object code is Elixir.HTTPotion


 
22:02:08.524 [error] Loading of /Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/httpotion/ebin/Elixir.Httpotion.beam failed: :badfile 

 
22:02:08.525 [error] beam/beam_load.c(1428): Error loading module 'Elixir.Httpotion':
  module name in object code is Elixir.HTTPotion


 
22:02:08.525 [error] Loading of /Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/httpotion/ebin/Elixir.Httpotion.beam failed: :badfile 

 
== Compilation error in file lib/hub.ex ==
** (UndefinedFunctionError) function Httpotion.start/0 is undefined (module Httpotion is not available)
    Httpotion.start()
    lib/hub.ex:15: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

ぐぬぬ。戻してリトライしたら通った?

      {:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.0"},
      {:poison, "~> 1.3.0"},
      {:httpotion, "~> 1.0.0"}

で、以下?

$ mix deps.clean poison
* Cleaning poison
$ mix deps.clean httpotion
* Cleaning httpotion
$ mix deps.clean ibrowse
* Cleaning ibrowse
$ mix deps.get
* Getting ibrowse (https://github.com/cmullaparthi/ibrowse.git)
remote: Enumerating objects: 1493, done.        
remote: Total 1493 (delta 0), reused 0 (delta 0), pack-reused 1493        
Receiving objects: 100% (1493/1493), 918.96 KiB | 505.00 KiB/s, done.
Resolving deltas: 100% (950/950), done.
Resolving Hex dependencies...
Dependency resolution completed:
Unchanged:
  poison 1.3.1
Downgraded:
  httpotion 3.1.1 => 1.0.0
* Getting poison (Hex package)
* Getting httpotion (Hex package)

どうなんだろう。

駄目

最後のだけ。

==> hub
** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

これ、何だろ

別途確認、なのかな。

===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

もう少し

ibrowse だけにして

      {:ibrowse, github: "cmullaparthi/ibrowse", tag: "v4.1.0"},
#      {:poison, "~> 1.3.0"},
#      {:httpotion, "~> 1.0.0"}

リトライしてみましたが

===> Compiling ibrowse
===> Compiling src/ibrowse_lib.erl failed
src/ibrowse_lib.erl:371: erlang:now/0: Deprecated BIF. See the "Time and Time Correction in Erlang" chapter of the ERTS User's Guide for more information.

** (Mix) Could not compile dependency :ibrowse, "/Users/rms/.mix/rebar3 bare compile --paths "/Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/*/ebin"" command failed. You can recompile this dependency with "mix deps.compile ibrowse", update it with "mix deps.update ibrowse" or clean it with "mix deps.clean ibrowse"

同じです。

あら?

できてたん?

22:32:08.947 [error] beam/beam_load.c(1428): Error loading module 'Elixir.Httpotion':
  module name in object code is Elixir.HTTPotion


 
22:32:08.947 [error] Loading of /Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/httpotion/ebin/Elixir.Httpotion.beam failed: :badfile 


22:32:08.947 [error] beam/beam_load.c(1428): Error loading module 'Elixir.Httpotion':
  module name in object code is Elixir.HTTPotion



22:32:08.947 [error] Loading of /Users/rms/Documents/elixir/metaprogramming-elixir/hub/_build/dev/lib/httpotion/ebin/Elixir.Httpotion.beam failed: :badfile

 
== Compilation error in file lib/hub.ex ==
** (UndefinedFunctionError) function Httpotion.start/0 is undefined (module Httpotion is not available)
    Httpotion.start()
    lib/hub.ex:15: (module)
    (stdlib) erl_eval.erl:680: :erl_eval.do_apply/6

一旦置きますorz

Metaprogramming Elixir (9) Metaprogramming Elixir (11)

comments powered by Disqus