首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >未定义的start_link代理

未定义的start_link代理
EN

Stack Overflow用户
提问于 2017-11-12 17:52:02
回答 1查看 65关注 0票数 0

我正在跟踪一本菲尼克斯的书,并构建一个代理来使用上面的几个后端:

代码语言:javascript
复制
# Proxy
defmodule Rumbl.InfoSys do
  # we will have several backends; wolfram, google search, google pictures, etc
  @backends [Rumbl.InfoSys.WolFram]

  defmodule Result do
    defstruct score: 0, text: nil, url: nil, backend: nil
  end

  def start_link(backend, query, query_ref, owner, limit) do
    backend.start_link(query, query_ref, owner, limit)
  end

  def compute(query, opts \\ []) do
    limit = opts[:limit] || 10
    backends = opts[:backends] || @backends

    backends
    |> Enum.map(&spawn_query(&1, query, limit))
  end

  defp spawn_query(backend, query, limit) do
    query_ref = make_ref()
    opts = [backend, query, query_ref, self(), limit]
    {:ok, pid} = Supervisor.start_child(Rumbl.InfoSys.Supervisor, opts)
    {pid, query_ref}
  end
end

现在我只定义了一个后端,Rumbl.InfoSys.WolFram

以下是wolfram后端的定义

代码语言:javascript
复制
defmodule Rumbl.InfoSys.Wolfram do
  import SweetXml
  alias Rumbl.InfoSys.Result

  def start_link(query, query_ref, owner, limit) do
    Task.start_link(__MODULE__, :fetch, [query, query_ref, owner, limit])
  end

  def fetch(query_str, query_ref, owner, _limit) do
    query_str
    |> fetch_xml()
    |> xpath(~x"/queryresult/pod[contains(@title, 'Result') or
                                 contains(@title, 'Definitions')]
                                 /subpod/plaintext/text()")
    |> send_results(query_ref, owner)
  end

  defp send_results(nil, query_ref, owner) do
    send(owner, {:results, query_ref, []})
  end

  defp send_results(answer, query_ref, owner) do
    results = [%Result{backend: "wolfram", score: 95, text: to_string(answer)}]
    send(owner, {:results, query_ref, results})
  end

  defp fetch_xml(query_str) do
    {:ok, {_, _, body}} = :httpc.request(
      String.to_char_list("http://api.wolframalpha.com/v2/query" <>
        "?appid=#{app_id()}" <>
        "&input=#{URI.encode(query_str)}&format=plaintext"))
    body
  end

  defp app_id, do: Application.get_env(:rumbl, :wolfram)[:app_id]
end

在这本书中,一旦定义了wolfram后端,它就会告诉您在shell中测试它:

代码语言:javascript
复制
iex> Rumbl.InfoSys.compute("what is elixir?")
[{#PID<0.1703.0>, #Reference<0.0.3.8938>}]

但对我来说,这只是一项工作:

代码语言:javascript
复制
iex(1)> Rumbl.InfoSys.compute("what is elixir?")
** (MatchError) no match of right hand side value: {:error, {:EXIT, {:undef, [{Rumbl.InfoSys.WolFram, :start_link, ["what is elixir?", #Reference<0.1501712023.3692298244.231940>, #PID<0.521.0>, 10], []}, {:supervisor, :do_start_child_i, 3, [file: 'supervisor.erl', line: 381]}, {:supervisor, :handle_call, 3, [file: 'supervisor.erl', line: 406]}, {:gen_server, :try_handle_call, 4, [file: 'gen_server.erl', line: 636]}, {:gen_server, :handle_msg, 6, [file: 'gen_server.erl', line: 665]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 247]}]}}}
    (rumbl) lib/rumbl/info_sys.ex:25: Rumbl.InfoSys.spawn_query/3
    (elixir) lib/enum.ex:1270: Enum."-map/2-lists^map/1-0-"/2

只要我理解,它就会抱怨start_link Rumbl.InfoSys.Wolfram没有定义?

代码语言:javascript
复制
:undef, [{Rumbl.InfoSys.WolFram, :start_link

我认为这与这本书有点老,凤凰和灵丹妙药的版本不同有关,但不知道如何修复它。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-12 20:34:35

看起来编译器正在告诉您一切-- Supervisor.start_child正在返回一个错误元组,您的模式匹配在第25行失败:

代码语言:javascript
复制
{:ok, pid} = Supervisor.start_child(Rumbl.InfoSys.Supervisor, opts)

消息还说Rumbl.InfoSys.WolFram是未定义的,当我查看WolFram模块定义时,它的名称是Rumbl.InfoSys.Wolfram。请更新模块的名称,并考虑将错误路径添加到模式匹配中,在spawn_query/3函数中:)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47252007

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档