【问题标题】:What is this Elixir message means这个 Elixir 消息是什么意思
【发布时间】:2015-06-22 17:33:53
【问题描述】:

我正在编写 Elixir 以从远程节点获取记录,我已经编写了一个模块,

   defmodule Connect do
      def connect do
      node_ap_dev_ejd = :'abc@abc.com'
      :net_adm.ping(node_ap)

      fbUsersFun = fn(x) -> :binary.part(x,{0,3}) == <<"*ab">> end
      f = fn()-> :mnesia.dirty_select(:'cz_map',[{{:cz_map, :'$1', :'_',:'_',:'_'},[],[:'$1']}]) end

      fbUserList = :rpc.call(node_ap_dev_ejd,:mnesia,:activity,[:async_dirty,f])
      list = Enum.filter(fbUserList ,fbUsersFun)
      length(list)
      end
   end    

如果我将代码逐行放入iex shell中我可以运行,但是如果我编译代码并运行Connect.connect,就会出现这个错误,我不知道它,请建议

** (Protocol.UndefinedError) protocol Enumerable not implemented for 
{:badrpc, {:EXIT, {:undef, [{#Function<1.96315226/0 in Connect.connect/0>, [], []}, {:mnesia_tm, :non_transaction, 5, [file: 'mnesia_tm.erl', line: 738]}]}}}
(elixir) lib/enum.ex:1: Enumerable.impl_for!/1
(elixir) lib/enum.ex:112: Enumerable.reduce/3
(elixir) lib/enum.ex:666: Enum.filter/2
         second_function.ex:10: Connect.connect/0

【问题讨论】:

    标签: erlang elixir mnesia


    【解决方案1】:

    表示数据{:badrpc, ...}没有实现Enumerable protocol

    这个错误很可能来自这一行:

    list = Enum.filter(fbUserList ,fbUsersFun)
    

    在该行中,您正在尝试过滤 fbUserList,我猜它是 {:badrpc, ...} 而不是可枚举的。元组不是可枚举的;列表和地图(以及其他东西)是。

    解决方案可能在于case 表达式,它检查:rpc.call/4 返回的结果以防止错误:

    case :rpc.call(node_ap_dev_ejd, :mnesia, :activity, [:async_dirty, f]) do
      {:badrpc, _} -> raise "bad rpc error"
      fbUserList   -> Enum.filter(fbUserList, ...) # and so on
    end
    

    【讨论】:

    • 您好,谢谢您的回答。我检查了 Elixir 文档,发现 Enum.filter 将处理集合,其中包括元组。使用案例后,我发现:rpc.call(node_ap_dev_ejd, :mnesia, :activity, [:async_dirty, f]) 总是引发“bad rpc error”。但是很奇怪,如果我直接在shell中运行`"rpc.call(node_ap_dev_ejd, ...) 就运行成功了,不知道有什么区别。
    • @PeterHon Enum.filter/2 处理集合,因为 Enumerable 协议未针对元组实现。尝试在 IEx 中运行 Enum.filter({1, 2}, fn(el) -&gt; el &gt; 1 end),以便您自己验证:)。
    • 谢谢。但是对于 case 语句,它总是会引发错误。我想知道为什么 rpc.call 在 iex 中有效但在模块中无效。
    • @PeterHon 如果我不得不猜测的话,我会说一些时间问题:shell 中的调用发生在彼此“遥远”的地方,因为你需要时间来键入它们,而正在执行的代码正在执行几乎没有延迟。
    • 谢谢。一样的猜测。也许我需要在 rpc 调用之后把时间休眠。不过我觉得灵药应该处理得当。
    【解决方案2】:

    我在使用 erlang 处理 mnesia 时遇到了同样的问题,错误是因为匿名函数“f”,问题是远程节点无法识别该函数,因为它是在另一个节点中创建的。

    编辑:

    我设法在 erlang 中解决了这个问题,我将向您展示我是如何在 erlang 中做到的,我对 elixir 了解不多,但我确信它是否可以在 erlang 中完成,它会在 elixir 中完成。

    所以这一段

     f = fn()-> :mnesia.dirty_select(:'cz_map',[{{:cz_map, :'$1', :'_',:'_',:'_'},[],[:'$1']}]) end
    
      fbUserList = :rpc.call(node_ap_dev_ejd,:mnesia,:activity,[:async_dirty,f])
    

    在erlang中是这样的

    f = fun()-> mnesia:dirty_select(cz_map,[{{cz_map, '$1', '_', '_', '_'},[],['$1']}]) end,
    fbUserList = rpc:call(node_ap_dev_ejd, mnesia, activity, [async_dirty, f])
    

    你必须做这样的事情,而不是声明一个匿名的乐趣

    fbUserList = rpc:call(node_ap_dev_ejd, mnesia, activity, [async_dirty, mnesia:dirty_select/2, [cz_map, [{{cz_map, '$1', '_', '_', '_'},[],['$1']}]]])
    

    你可以在这里找到明确的解释what kind of types can be sent on an erlang message?

    希望这些信息对您有所帮助。

    【讨论】:

    • 您能否在答案中添加更多详细信息?
    • 抱歉,我还在处理这个问题,等有什么好的时候再贴出来​​
    猜你喜欢
    • 2010-10-01
    • 1970-01-01
    • 2021-12-26
    • 1970-01-01
    • 1970-01-01
    • 2015-04-14
    • 2011-12-17
    • 1970-01-01
    • 2011-09-07
    相关资源
    最近更新 更多