Io 如何在Elixir中写入标准输入?

Io 如何在Elixir中写入标准输入?,io,elixir,Io,Elixir,我有一个用于检查数字奇偶性的模块: defmodule Parity do def start() do continue() end defp continue() do get_number() |> parse() |> even?() |> print_output() continue() end defp get_number() do IO.gets("Type a number: "

我有一个用于检查数字奇偶性的模块:

defmodule Parity do
  def start() do
    continue()
  end

  defp continue() do
    get_number()
    |> parse()
    |> even?()
    |> print_output()
    continue()
  end

  defp get_number() do
    IO.gets("Type a number: ")
  end

  defp parse(input) do
    String.trim(input)
    |> Integer.parse
  end

  defp even?({ number, _ }) do
    Integer.mod(number, 2) == 0
  end

  defp print_output(_is_even = true) do
    IO.puts("This number is even!")
  end

  defp print_output(_is_odd) do
    IO.puts("This number is odd!")
  end
end
它的工作原理如下:

$ mix run -e Parity.start
Type a number: 4
This number is even!
Type a number: 3
This number is odd!
Type a number: 68
This number is even!
Type a number: 1
This number is odd!
Type a number: ...
defmodule Bot do
  def start() do
    Parity.start()
    provide_number()
  end

  defp provide_number() do
    random_number()
    |> IO.puts
    provide_number()
  end

  defp random_number() do
    Enum.random(0..100)
  end
end
现在我想要另一个模块,它能够
奇偶校验
模块将数字写入标准输入
。所以我需要有一个执行
Parity.start()
的工具,然后为
IO.get()函数提供数字。
我试过这样的方法:

$ mix run -e Parity.start
Type a number: 4
This number is even!
Type a number: 3
This number is odd!
Type a number: 68
This number is even!
Type a number: 1
This number is odd!
Type a number: ...
defmodule Bot do
  def start() do
    Parity.start()
    provide_number()
  end

  defp provide_number() do
    random_number()
    |> IO.puts
    provide_number()
  end

  defp random_number() do
    Enum.random(0..100)
  end
end
但它不起作用


它只启动奇偶校验模块,但没有来自
provide_number()
函数的输入。

如果您想写入stdin(就像伪造CLI输入一样),您非常需要一种在不同系统进程之间交换信息的方法。这很好:

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

  proc = %Proc{pid: pid} =
    Porcelain.spawn_shell("mix run -e Parity.start", in: :receive, out: {:send, self()})

  Proc.send_input(proc, "1")
  receive do
    {^pid, :data, :out, data} -> IO.inspect data   #=> "This number is odd!"
  end
end
未经测试而编写,但这应该会让您大致了解。瓷器在这方面比
System.cmd/3
好得多。或者,如果您不需要stdin,则应在其上运行每个模块:

然后在
OtherModule
中,您可以编写如下内容:

pid = Node.spawn_link :"parity@computer-name", fn -> ... end

您正在一个线程中运行这一切。当您调用
Bot.start/0
时,它将调用
Parity.start/0
,它最终将调用
IO.get/2
。您的程序现在正在等待输入,无法继续对实际生成数字的部分执行代码。您这样做的目的是什么?是为了测试吗?@RyanBigg我只想用另一个模块模拟人的输入。