2016-10-14 9 views
0

私はporcelain moduleでElixirからinteropを行う方法を学ぼうとしています。PythonスクリプトにElixir磁器を使ってメッセージを送る方法は?

だから私はこの単純な例作られた:

私はこのようになりますエリクサー機能を持っている:

defmodule PythonMessenger do 
    alias Porcelain.Process, as: Proc 
    alias Porcelain.Result 

    def test_messages do 
    proc = %Proc{pid: pid} = 
     Porcelain.spawn_shell("python ./python_scripts/reply_to_elixir.py", 
     in: :receive, out: {:send, self()}) 

    Proc.send_input(proc, "Greetings from Elixir\n") 

    data = receive do 
     {^pid, :data, :out, data} -> data 
    end 

    IO.inspect data 

    Proc.send_input(proc, "Elixir: I heard you said \"#{data}\"\n") 

    data = receive do 
     {^pid, :data, data} -> data 
    end 

    IO.inspect data 

    Proc.send_input(proc, "Please quit\n") 

    data = receive do 
     {^pid, :data, data} -> data 
    end 

    IO.inspect data 
    end 
end 

とこのようになりますPythonスクリプト:

import sys 

while 1: 

    line = sys.stdin.readline() 
    if "quit" in line: 
     print("Quitting, bye for now") 
     sys.exit() 
    print(line) 

が、これを動作しません。 Pythonスクリプトは決して終了しません。 のような読みちょうど1行場合:

line = sys.stdin.readline() 

は、それだけで正常に動作します。

だから問題は何ですか?

+1

ない、それ自体が答えはいますが、アーランの外部ターム・フォーマットを見てみたいことがあります。件名に関するこのQ&Aをご覧ください:http://stackoverflow.com/questions/5050758/erlang-interface-to-python –

+1

erlportsパッケージでは、ただの文字列。 http://erlport.org/ –

+0

ありがとう、erlportはこれのために磁器よりはるかに良い選択肢と思われます。 –

答えて

2

sys.stdin.readline()でバッファリングを無効にするには、-uを渡す必要があります。対話的にプログラムを実行しているときは表示されませんが、プログラムがTTYなしで生成されたときに表示されます。デフォルトのバッファリングのため、Pythonプロセスは"Greetings from Elixir\n"のような短いメッセージのために何も印刷していませんでした。receiveという式のために、Pythonプロセスが何かを印刷するのを待って、Elixirコードが永久にブロックされていました。 man pythonから

-u  Force stdin, stdout and stderr to be totally unbuffered. On systems where it matters, also 
      put stdin, stdout and stderr in binary mode. Note that there is internal buffering in xread- 
      lines(), readlines() and file-object iterators ("for line in sys.stdin") which is not influ- 
      enced by this option. To work around this, you will want to use "sys.stdin.readline()" inside 
      a "while 1:" loop. 

また、いくつかの第二の間違いや第三receiveパターンを持っていました。

defmodule PythonMessenger do 
    alias Porcelain.Process, as: Proc 
    alias Porcelain.Result 

    def test_messages do 
    proc = %Proc{pid: pid} = 
     Porcelain.spawn_shell("python -u ./a.py", 
     in: :receive, out: {:send, self()}) 

    Proc.send_input(proc, "Greetings from Elixir\n") 

    data = receive do 
     {^pid, :data, :out, data} -> data 
    end 

    IO.inspect data 

    Proc.send_input(proc, "Elixir: I heard you said \"#{data}\"\n") 

    data = receive do 
     {^pid, :data, :out, data} -> data 
    end 

    IO.inspect data 

    Proc.send_input(proc, "Please quit\n") 

    data = receive do 
     {^pid, :data, :out, data} -> data 
    end 

    IO.inspect data 
    end 
end 

PythonMessenger.test_messages 

出力:ここでは私のために動作するコードです

"Greetings from Elixir\n\n" 
"Elixir: I heard you said \"Greetings from Elixir\n\n\n\n" 
"\"\n\n" 
+0

動作しますが、最後のメッセージは受信されません:-( –

+0

これはおそらく 'Proc.send_input(proc、" Elixir:あなたが\ "#{data} \" \ n ")'改行とその入力を複数の行として読み取るPythonスクリプト。 – Dogbert

関連する問題