Mike J
Mike J

Reputation: 93

Erlang: looping a function for each element in a list

I have a calls.txt:

{john, [jill,joe,bob]}.

{jill, [bob,joe,bob]}.

{sue, [jill,jill,jill,bob,jill]}.

{bob, [john]}.

{joe, [sue]}.

I want to loop through Receiver1 and call the spawner() function for each element in Receiver1. However, when I call read() in the console, nothing happens. Please help

Here's my code:

read() -> 
    {ok, [List1, List2, List3, List4, List5]} = 
    file:consult("calls.txt"),
    {Sender1, Receiver1} = List1,
    {Sender2, Receiver2} = List2,
    {Sender3, Receiver3} = List3,
    {Sender4, Receiver4} = List4,
    {Sender5, Receiver5} = List5,
    [spawner(Sender1,H) || H <- Receiver1].

spawner(Sname,Rname) ->
    Sender = spawn(calling,intercept,[]),
    Sender ! {self(), {Sname,Rname}},
    get_feedback().

get_feedback() ->
    receive
        {Msg} -> 
            io:fwrite(Msg)
    end.

Upvotes: 0

Views: 676

Answers (1)

7stud
7stud

Reputation: 48599

get_feedback() executes in the main/original process. Just because the call to get_feedback() occurs after the call to spawn() does not mean that get_feedback() executes in the spawned process. The only thing that executes in the spawned process is the function calling:intercept().

As a result, you end up sending a message to the spawned process, then you enter a receive in the main process when you call get_feedback()--which means the main process waits for a message from the spawned process, yet the spawned process doesn't send any messages (or at least you haven't shown any code where the spawned process sends a message to the main process).

If you call get_feedback() inside the function calling:intercept(), then get_feedback() will execute in the spawned process--and the receive will try to match messages sent by the main process to the spawned process.

Also, if for some reason a receive won't match a message and you think it should, then rewrite the receive like this:

receive 
    Msg -> io:format("~w~n", [Msg])
end

That receive will match any message, then you can examine the output to determine why your actual receive isn't matching.

Or, you can have intercept() send a msg back to the main process, and then get_feedback() can receive the message in the main process:

-module(my).
-compile(export_all).

read() ->
    {ok, Pairs} = file:consult("calls.txt"),
    [spawner(Sender, Receivers) || {Sender, Receivers} <- Pairs]. 

spawner(Sender, Receivers) ->
    io:format("~w, ~w~n", [Sender, Receivers]),
    Pid = spawn(my, intercept, []),
    io:format("The main process is: ~w.~n", [self()]),
    io:format(
        "The newly spawned process where intercept() is executing is: ~w~n", 
        [Pid]
     ),

    Pid ! {self(), {Sender, Receivers} },
    get_feedback().


intercept() ->
    receive
        {From, Pair} -> 
            io:format("intercept() received message: ~w, from: ~w~n", [Pair, From]),
            From ! {self(), "hello"}
    end.

get_feedback() ->
    receive
        {From, Msg} ->
            io:format("Main process received message: ~p, from: ~w~n", [Msg, From])
    end.

In the shell:

18> c(my).    
my.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,my}

19> my:read().
john, [jill,joe,bob]
The main process is: <0.64.0>.
The newly spawned process where intercept() is executing is: <0.168.0>
intercept() received message: {john,[jill,joe,bob]}, from: <0.64.0>
Main process received message: "hello", from: <0.168.0>
jill, [bob,joe,bob]
The main process is: <0.64.0>.
The newly spawned process where intercept() is executing is: <0.169.0>
intercept() received message: {jill,[bob,joe,bob]}, from: <0.64.0>
Main process received message: "hello", from: <0.169.0>
sue, [jill,jill,jill,bob,jill]
The main process is: <0.64.0>.
The newly spawned process where intercept() is executing is: <0.170.0>
intercept() received message: {sue,[jill,jill,jill,bob,jill]}, from: <0.64.0>
Main process received message: "hello", from: <0.170.0>
bob, [john]
The main process is: <0.64.0>.
The newly spawned process where intercept() is executing is: <0.171.0>
intercept() received message: {bob,[john]}, from: <0.64.0>
Main process received message: "hello", from: <0.171.0>
joe, [sue]
The main process is: <0.64.0>.
The newly spawned process where intercept() is executing is: <0.172.0>
intercept() received message: {joe,[sue]}, from: <0.64.0>
Main process received message: "hello", from: <0.172.0>
[ok,ok,ok,ok,ok]

Upvotes: 1

Related Questions