[英]Elixir: How can I describe mix.exs settings correctly?
I tried to write a web scraping tool by using HTTPoison. 我尝试使用HTTPoison编写Web抓取工具。 As a first step, I wrote a short HTTP accessing code along the steps shown below; 第一步,按照下面显示的步骤编写了一个简短的HTTP访问代码。
Create a project by mix 通过混合创建项目
$ mix new httptest1 $混合新的httptest1
Write a short code on lib/httptest1.ex. 在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()
Modify mix.exs for HTTPoison. 为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
Run $ mix deps.get
for dependency. 运行$ mix deps.get
作为依赖项。
Run $ mix run
, then compilation failed; 运行$ 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
When I used $ iex -S mix
instead, the result was same. 当我改用$ iex -S mix
,结果是一样的。
But if I moved httptest1.ex to the same directory where mix.exs was placed, like $ mv lib/httptest1.ex .
但是,如果我将httptest1.ex移到了mix.exs所在的目录中,例如$ mv lib/httptest1.ex .
and tried to specify the source file explicitly; 并尝试明确指定源文件; $ mix run httptest1
, it worked correctly. $ mix run httptest1
,它可以正常工作。
Question: I suspect my mix.exs setting goes something wrong, what's that? 问题:我怀疑我的mix.exs设置出了问题,那是什么?
All .ex
in lib/
are compiled. lib/
中的所有.ex
都已编译。 Since Elixir is meta-programming language when you compile a file you are actually running the code. 由于Elixir是编译文件时的元编程语言,因此实际上是在运行代码。 Which means that Httptest1.test1()
is executed when you compile your project. 这意味着在编译项目时将执行Httptest1.test1()
。
HTTPoison needs to be started for it work correctly. 需要启动HTTPoison才能正常工作。 It is started when your application starts which it is when you do mix run ...
. 它在您的应用程序启动时启动,而在您进行mix run ...
时即启动。 But when your project is compiling your project or your dependencies are not started so calls to your dependencies might fail. 但是,当您的项目正在编译时,或者您的依赖项没有启动,因此对您的依赖项的调用可能会失败。
Check out this chapter Supervisor and Application in the getting started guide to learn how to run code when your application starts. 查阅入门指南中的本章“管理程序和应用程序” ,以了解如何在应用程序启动时运行代码。
Improved! 改进! Now I know how to create an executable invoked command line. 现在,我知道如何创建可执行文件调用的命令行了。
program; 程序;
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
and mix.exs (both created by $ mix new httptest1 --sup
supervisor option); 和mix.exs(均由$ mix new httptest1 --sup
创建$ 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
Then in the iex invoked by $ iex -S mix
type Httptest.test1
, the expected result comes up! 然后在$ iex -S mix
类型Httptest.test1调用的Httptest.test1
,出现预期的结果! Thanks. 谢谢。
Also, to create command line executable, 另外,要创建命令行可执行文件,
$ mix escript.build
then ./httptest1 is generated. 然后生成./httptest1。 Done. 完成。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.