Reputation: 849
I have this module for checking the parity of numbers:
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
And it works like this:
$ 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: ...
Now I want to have another module, which would be able to write numbers to the standard input for the Parity
module. So I need to have a something for executing Parity.start()
and then providing numbers to IO.gets()
function.
I tried something like this:
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
And it doesn't work.
It only starts Parity
module, but there is no input from the provide_number()
function.
Upvotes: 3
Views: 1212
Reputation: 6981
If you want to write to stdin (like the equivalent of faking a CLI input) you pretty much need a way to exchange info between different system processes. Porcelain does that pretty well:
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
Written without testing, but that should give you a rough idea. Porcelain has a much better handle on this than System.cmd/3
. Alternatively, if you don't need stdin, you should run each module on their own Elixir node:
iex --sname parity -S mix
Then in your OtherModule
you can write something like:
pid = Node.spawn_link :"parity@computer-name", fn -> ... end
Upvotes: 3