LoginSignup
23
24

More than 5 years have passed since last update.

naoya@githubさんの記事を試すには

Last updated at Posted at 2015-08-23

naoya@githubさんが最近「カッとなって」Elixir関連の記事を投稿されていますが、さらにカッとなってWEB+DB PRESSに記事を書かれています。

でも、あのソースを見てもそのままでは実際に動かせなかった人も多いのでは。次号以降に補足が出るにしても隔月刊ですしね…

ということで復習も兼ねて動かし方を書いてみます。

ソース

ソースはこんな感じでした(写経)。一つ目の「あまりElixirらしくない」ものを対象にしました。

defmodule WeatherClient do
  def fetch_json(url) do
    HTTPoison.start
    res = HTTPoison.get!(url)
    Poison.decode!(res.body)
  end

  def get do
    %{"weather" => weather} = fetch_json(
      "http://api.openweathermap.org/data/2.5/weather?q=Tokyo.jp"
    )
    weather
  end
end

Enum.each WeatherClient.get, fn(w) ->
  IO.puts w["main"]
end

依存性のあるライブラリ

ここでは2つの依存性のあるライブラリが使われています1
HTTPoison
HTTPクライアントライブラリ。ErlangのHTTPクライアントライブラリhackneyをベースに作られている。以前に使いました。プロキシ設定が使えるのがうれしいケースもあり。
Poison
JSONライブラリ。Githubによれば単純さや完全さや正確さを全く犠牲にせず爆速、とのこと。

ですので、これらをどうにかして持ってきて使う必要があります。

mix new でプロジェクトを作り mix.exsを設定する

ではmixでプロジェクトを作ります。

$ mix new weatherclient --module WeatherClient
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/weatherclient.ex
* creating test
* creating test/test_helper.exs
* creating test/weatherclient_test.exs

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

    cd weatherclient
    mix test

Run `mix help` for more commands.

--module WeatherClientを付けたのはモジュール名をCamelCase(WeatherClient)にしたかったから。付けないとWeatherclientになります(そうなると写経したプログラムの方も合わせる必要があるのでめんどくさい)。
次に依存関係のあるライブラリを使うためにmix.exsを変更します。

$ cd weatherclient
$ ls
config  lib  mix.exs  README.md  test
$ vi mix.exs

(おっと、Vimmerなのがバレてしまった)お好みのエディタでmix.exsを以下のように変更します。

defmodule WeatherClient.Mixfile do
  use Mix.Project

  def project do
    [app: :weatherclient,
     version: "0.0.1",
     elixir: "~> 1.0",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     deps: deps]
  end

  # Configuration for the OTP application
  #
  # Type `mix help compile.app` for more information
  def application do
    [applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type `mix help deps` for more examples and options
  defp deps do
    [
      {:httpoison, "~> 0.6"},
      {:poison, "~> 1.4.0"}
    ]
  end
end

defp deps doのところがもともと[]になっているのでここに必要なライブラリ名とバージョン(~>は...以上の意)を設定します。

mix deps.getで必要なものを落としてくる

mix deps.getで必要なライブラリを落としてきましょう。

$ mix deps.get
Running dependency resolution
Dependency resolution completed successfully
  hackney: v1.3.1
  httpoison: v0.7.2
  idna: v1.0.2
  poison: v1.4.0
  ssl_verify_hostname: v1.0.5
* Getting httpoison (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/httpoison-0.7.2.tar)
...(中略)...
* Getting idna (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/idna-1.0.2.tar)
Using locally cached package
Unpacked package tarball (/home/azureuser/.hex/packages/idna-1.0.2.tar)

次はlib/webclient.exが最初は

defmodule WeatherClient do
end

という内容だけなのでこのファイルに「写経」します。

ビルドして実行する

mix runを実行します。

$ mix run
==> idna (compile)
Compiled src/idna.erl
...(中略)...
Compiled src/hackney_connect/hackney_cacerts.erl
Compiled src/hackney_lib/hackney_mimetypes.erl
==> httpoison
Compiled lib/httpoison/base.ex
Compiled lib/httpoison.ex
Generated httpoison app
Clouds
==> weatherclient
Compiled lib/weatherclient.ex
Generated weatherclient app

おしまいの方にちょろっと
Clouds(曇り)
と出てるのが結果です。

2回めからは

$ mix run lib/weatherclient.ex

と実行してください。

lib/weatherclient.ex:1: warning: redefining module WeatherClient
Clouds

と結果の前に警告が出ますが気にしなくていいようです。

iex -S mixを使う

プログラムが実際何をやっているか見るにはiexを使いましょう。

$ iex -S mix
Erlang/OTP 18 [erts-7.0] [source] [64-bit] [async-threads:10] [hipe] [kernel-poll:false]

Interactive Elixir (1.0.5) - press Ctrl+C to exit (type h() ENTER for help)

ここでモジュールWeatherClientの関数を直に叩くと

iex(1)> WeatherClient.get
[%{"description" => "overcast clouds", "icon" => "04n", "id" => 804,
   "main" => "Clouds"}]

という中身が返ってきていることがわかります2。元のプログラムの一番下3行はこの結果の中からキー"main"の値の部分だけ取り出していたのです。続けて確認しましょう。

iex(2)> Enum.each WeatherClient.get, fn(w) ->
...(2)>   IO.puts w["main"]
...(2)> end
Clouds
:ok
iex(3)>

  1. Elixirがそもそも「霊薬」なのでもじって薬やら毒関係の名前のライブラリが多いような気がします。 

  2. mapのlistです。 

23
24
0

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
23
24