Elixir:如何正确描述 mix.exs 设置?
Elixir: How can I describe mix.exs settings correctly?
我尝试使用 HTTPoison 编写一个网络抓取工具。作为第一步,我按照如下所示的步骤编写了一个简短的 HTTP 访问代码;
通过 mix 创建项目
$ 混合新 httptest1
在lib/httptest1.ex.上写一个短代码
defmodule Httptest1 do
require HTTPoison
def test1 do
ret = HTTPoison.get! "http://www.yahoo.com"
%HTTPoison.Response{status_code: 200, body: body} = ret
IO.inspect body
end
end
Httptest1.test1()
为 HTTPoison 修改 mix.exs。
defmodule Httptest1.Mixfile do
use Mix.Project
def project do
[app: :httptest1,
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
def application do
[applications: [:logger, :httpoison]]
end
# Dependencies can be Hex packages:
#
defp deps do
[
{:httpoison, "~> 0.6"}
]
end
end
运行 $ mix deps.get
依赖。
运行$ mix run
,则编译失败;
==> idna (compile)
Compiled src/idna.erl
Compiled src/idna_ucs.erl
Compiled src/punycode.erl
(... snip ...)
Generated httpoison app
== Compilation error on file lib/httptest1.ex ==
** (exit) exited in: :gen_server.call(:hackney_manager, {:new_request, #PID<0.154.0>, #Reference<0.0.1.1724>, {:client, :undefined, :hackney_dummy_metrics, :hackney_tcp_transport, 'www.yahoo.com', 80, "www.yahoo.com", [connect_timeout: 5000, recv_timeout: :infinity], nil, nil, nil, true, :hackney_pool, :infinity, false, 5, false, 5, nil, nil, nil, :undefined, :start, nil, :normal, false, false, false, false, nil, :waiting, nil, 4096, "", [], :undefined, nil, nil, nil, nil, :undefined, nil}}, :infinity)
** (EXIT) no process
(stdlib) gen_server.erl:212: :gen_server.call/3
src/hackney_client/hackney_manager.erl:66: :hackney_manager.init_request/1
src/hackney_client/hackney_manager.erl:56: :hackney_manager.new_request/1
src/hackney_connect/hackney_connect.erl:181: :hackney_connect.socket_from_pool/4
src/hackney_connect/hackney_connect.erl:36: :hackney_connect.connect/5
src/hackney_client/hackney.erl:319: :hackney.request/5
lib/httpoison.ex:60: HTTPoison.request/5
lib/httpoison.ex:60: HTTPoison.request!/5
当我使用 $ iex -S mix
时,结果是一样的。
但是如果我将 httptest1.ex 移动到放置 mix.exs 的相同目录,例如 $ mv lib/httptest1.ex .
并尝试明确指定源文件; $ mix run httptest1
,它工作正常。
问题:
我怀疑我的 mix.exs 设置有问题,那是什么?
lib/
中的.ex
全部编译。由于 Elixir 是元编程语言,因此当您编译文件时,您实际上是在 运行 编译代码。这意味着 Httptest1.test1()
在编译项目时执行。
需要启动 HTTPPoison 才能正常工作。它在您的应用程序启动时启动,也就是您执行 mix run ...
时启动。但是当你的项目正在编译你的项目或者你的依赖项没有启动时,调用你的依赖项可能会失败。
查看入门指南中的本章Supervisor and Application,了解如何在应用程序启动时运行编码。
改进了!现在我知道如何创建一个可执行的调用命令行了。
程序;
defmodule Httptest1 do
use Application
require HTTPoison
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = []
opts = [strategy: :one_for_one, name: Httptest1.Supervisor]
Supervisor.start_link(children, opts)
end
def main(args) do # entry point
ret = HTTPoison.get! "http://www.yahoo.com"
%HTTPoison.Response{status_code: _, body: body} = ret # no status code matching now
IO.inspect body
end
end
和mix.exs(均由$ mix new httptest1 --sup
主管选项创建);
defmodule Httptest1.Mixfile do
use Mix.Project
def project do
[app: :httptest1,
version: "0.0.1",
elixir: "~> 1.0",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
escript: escript, # <<<< Added
deps: deps]
end
def escript do # define escript
[main_module: Httptest1]
end
def application do
[applications: [:logger, :httpoison],
mod: {Httptest1, []}] #
end
defp deps do
[
{:httpoison, "~> 0.6"}
]
end
end
然后在$ iex -S mix
调用的iex中输入Httptest.test1
,预期的结果出现了!谢谢。
此外,要创建命令行可执行文件,
$ mix escript.build
然后生成./httptest1。完成。
我尝试使用 HTTPoison 编写一个网络抓取工具。作为第一步,我按照如下所示的步骤编写了一个简短的 HTTP 访问代码;
通过 mix 创建项目
$ 混合新 httptest1
在lib/httptest1.ex.上写一个短代码
defmodule Httptest1 do require HTTPoison def test1 do ret = HTTPoison.get! "http://www.yahoo.com" %HTTPoison.Response{status_code: 200, body: body} = ret IO.inspect body end end Httptest1.test1()
为 HTTPoison 修改 mix.exs。
defmodule Httptest1.Mixfile do use Mix.Project def project do [app: :httptest1, 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 def application do [applications: [:logger, :httpoison]] end # Dependencies can be Hex packages: # defp deps do [ {:httpoison, "~> 0.6"} ] end end
运行
$ mix deps.get
依赖。运行
$ mix run
,则编译失败;==> idna (compile) Compiled src/idna.erl Compiled src/idna_ucs.erl Compiled src/punycode.erl (... snip ...) Generated httpoison app == Compilation error on file lib/httptest1.ex == ** (exit) exited in: :gen_server.call(:hackney_manager, {:new_request, #PID<0.154.0>, #Reference<0.0.1.1724>, {:client, :undefined, :hackney_dummy_metrics, :hackney_tcp_transport, 'www.yahoo.com', 80, "www.yahoo.com", [connect_timeout: 5000, recv_timeout: :infinity], nil, nil, nil, true, :hackney_pool, :infinity, false, 5, false, 5, nil, nil, nil, :undefined, :start, nil, :normal, false, false, false, false, nil, :waiting, nil, 4096, "", [], :undefined, nil, nil, nil, nil, :undefined, nil}}, :infinity) ** (EXIT) no process (stdlib) gen_server.erl:212: :gen_server.call/3 src/hackney_client/hackney_manager.erl:66: :hackney_manager.init_request/1 src/hackney_client/hackney_manager.erl:56: :hackney_manager.new_request/1 src/hackney_connect/hackney_connect.erl:181: :hackney_connect.socket_from_pool/4 src/hackney_connect/hackney_connect.erl:36: :hackney_connect.connect/5 src/hackney_client/hackney.erl:319: :hackney.request/5 lib/httpoison.ex:60: HTTPoison.request/5 lib/httpoison.ex:60: HTTPoison.request!/5
当我使用 $ iex -S mix
时,结果是一样的。
但是如果我将 httptest1.ex 移动到放置 mix.exs 的相同目录,例如 $ mv lib/httptest1.ex .
并尝试明确指定源文件; $ mix run httptest1
,它工作正常。
问题: 我怀疑我的 mix.exs 设置有问题,那是什么?
lib/
中的.ex
全部编译。由于 Elixir 是元编程语言,因此当您编译文件时,您实际上是在 运行 编译代码。这意味着 Httptest1.test1()
在编译项目时执行。
需要启动 HTTPPoison 才能正常工作。它在您的应用程序启动时启动,也就是您执行 mix run ...
时启动。但是当你的项目正在编译你的项目或者你的依赖项没有启动时,调用你的依赖项可能会失败。
查看入门指南中的本章Supervisor and Application,了解如何在应用程序启动时运行编码。
改进了!现在我知道如何创建一个可执行的调用命令行了。
程序;
defmodule Httptest1 do
use Application
require HTTPoison
def start(_type, _args) do
import Supervisor.Spec, warn: false
children = []
opts = [strategy: :one_for_one, name: Httptest1.Supervisor]
Supervisor.start_link(children, opts)
end
def main(args) do # entry point
ret = HTTPoison.get! "http://www.yahoo.com"
%HTTPoison.Response{status_code: _, body: body} = ret # no status code matching now
IO.inspect body
end
end
和mix.exs(均由$ mix new httptest1 --sup
主管选项创建);
defmodule Httptest1.Mixfile do
use Mix.Project
def project do
[app: :httptest1,
version: "0.0.1",
elixir: "~> 1.0",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
escript: escript, # <<<< Added
deps: deps]
end
def escript do # define escript
[main_module: Httptest1]
end
def application do
[applications: [:logger, :httpoison],
mod: {Httptest1, []}] #
end
defp deps do
[
{:httpoison, "~> 0.6"}
]
end
end
然后在$ iex -S mix
调用的iex中输入Httptest.test1
,预期的结果出现了!谢谢。
此外,要创建命令行可执行文件,
$ mix escript.build
然后生成./httptest1。完成。