簡體   English   中英

這段elixir代碼如何轉換為Erlang?

[英]How to convert this piece of elixir code to Erlang?

elixir中有一段代碼檢查節點是否存活,並在此基礎上進行一些操作。 如何在erlang實現同樣的功能?

def make_distributed([head | tail],l) do
        unless Node.alive?() do
            try do
                {ip_tuple,_,_} = head
                current_ip = to_string(:inet_parse.ntoa(ip_tuple))
                if current_ip === "127.0.0.1" do
                    if l > 1 do
                        make_distributed(tail,l-1)
                    else 
                        IO.puts "Could not make current node distributed."
                    end
                else
                    server_node_name = String.to_atom("client@" <> current_ip)
                    Node.start(server_node_name)
                    Node.set_cookie(server_node_name,:monster)
                    Node.connect(String.to_atom("server@" <> current_ip))
                end
            rescue
                _ -> if l > 1, do: make_distributed(tail,l-1), else: IO.puts "Could not make current node distributed."
            end
        end
    end

if...else 在 erlang 中的工作方式不同,我嘗試將其更改為該格式,但 elixir 代碼中的一些功能很難在 erlang 中顯示。

首先,直接翻譯...

make_distributed([Head | Tail], L) ->
  case node:is_alive() of
    false ->
      false; % Not sure what unless returns if the condition is false
    true ->
      try
        {IPTuple, _, _} = Head,
        CurrentIP = iolist_to_binary(inet_parse:ntoa(IPTuple)),
        case CurrentIP of
          <<"127.0.0.1">> ->
            case L of
              L when L > 1 ->
                make_distributed(Tail, L - 1);
              _ ->
                io:format("Could not make current node distributed.")
            end;
          _ ->
            ServerNodeName = binary_to_atom(<<"client@", CurrentIP/binary>>),
            net_kernel:start([ServerNodeName, longnames, 15000]),
            erlang:set_cookie(ServerNodeName, monster),
            net_kernel:connect_node(binary_to_atom(<<"server@", CurrentIP/binary>>))
        end
      catch
        _:_ ->
          case L of
            L when L > 1 ->
              make_distributed(Tail, L - 1);
            _ ->
              io:format("Could not make current node distributed.")
          end
      end
  end.

但那是一些非常難看的代碼。 讓我們更有效地使用模式匹配……

make_distributed([{IPTuple, _, _} | Tail], L) ->
  case node:is_alive() of
    false ->
      false; % Not sure what unless returns if the condition is false
    true ->
      try
        case iolist_to_binary(inet_parse:ntoa(IPTuple)) of
          <<"127.0.0.1">> when L > 1 ->
            make_distributed(Tail, L - 1);
          <<"127.0.0.1">> ->
                io:format("Could not make current node distributed.");
          CurrentIP ->
            ServerNodeName = binary_to_atom(<<"client@", CurrentIP/binary>>),
            net_kernel:start([ServerNodeName, longnames, 15000]),
            erlang:set_cookie(ServerNodeName, monster),
            net_kernel:connect_node(binary_to_atom(<<"server@", CurrentIP/binary>>))
        end
      catch
        _:_ when L > 1 ->
          make_distributed(Tail, L - 1);
        _:_ ->
          io:format("Could not make current node distributed.")
      end
  end.

不過……我們不需要在每個遞歸步驟中檢查節點活躍度,對吧?

maybe_make_distributed(IPTuples, L) ->
  case node:is_alive() of
    false ->
      false; % Not sure what unless returns if the condition is false
    true ->
      make_distributed(IPTuples, L)
  end.

make_distributed([{IPTuple, _, _} | Tail], L) ->
  try
    case iolist_to_binary(inet_parse:ntoa(IPTuple)) of
      <<"127.0.0.1">> when L > 1 ->
        make_distributed(Tail, L - 1);
      <<"127.0.0.1">> ->
        io:format("Could not make current node distributed.");
      CurrentIP ->
        ServerNodeName = binary_to_atom(<<"client@", CurrentIP/binary>>),
        net_kernel:start([ServerNodeName, longnames, 15000]),
        erlang:set_cookie(ServerNodeName, monster),
        net_kernel:connect_node(binary_to_atom(<<"server@", CurrentIP/binary>>))
    end
  catch
    _:_ when L > 1 ->
      make_distributed(Tail, L - 1);
    _:_ ->
      io:format("Could not make current node distributed.")
  end.

最后,讓我們像常規遞歸函數一樣將L > 1檢查移動到它自己的子句中……

maybe_make_distributed(IPTuples, L) ->
  case node:is_alive() of
    false ->
      false; % Not sure what unless returns if the condition is false
    true ->
      make_distributed(IPTuples, L)
  end.

make_distributed(_, 0) ->
  io:format("Could not make current node distributed.");
make_distributed([{IPTuple, _, _} | Tail], L) ->
  try
    case iolist_to_binary(inet_parse:ntoa(IPTuple)) of
      <<"127.0.0.1">> ->
        make_distributed(Tail, L - 1);
      CurrentIP ->
        ServerNodeName = binary_to_atom(<<"client@", CurrentIP/binary>>),
        net_kernel:start([ServerNodeName, longnames, 15000]),
        erlang:set_cookie(ServerNodeName, monster),
        net_kernel:connect_node(binary_to_atom(<<"server@", CurrentIP/binary>>))
    end
  catch
    _:_ ->
      make_distributed(Tail, L - 1)
  end.

現在這就是我將在 Erlang 中編寫的代碼,以實現與您的 Elixir 代碼相同的目標。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM