Search code examples
listerlangerl

Erlang: function with variable from another scope


Please, help me to write correctly function on Erlang. Function should remove packages (which successfully sent) from the queue. I think it should be like that, but it does not work. Erlang says: illegal pattern on line 3 :(

delete_pkts(AcksList, State) ->
  NewSendingList = lists:filter(fun(X) ->
    lists:any(fun(E) -> case E of X#internal_packet.message_number -> false; _ -> true end end, AcksList)
  end, State#state.pkt_send),
  State#state{ pkt_send = NewSendingList }.

Solution

  • I've never understood why, but you can't put a record field reference in a case clause. You could match out the field you're interested in in the function head instead:

    delete_pkts(AcksList, State) ->
      NewSendingList = lists:filter(fun(#internal_packet{message_number = MsgNo}) ->
        lists:any(fun(E) -> case E of MsgNo -> false; _ -> true end end, AcksList)
      end, State#state.pkt_send),
      State#state{ pkt_send = NewSendingList }.
    

    Alternatively, as the case expression just returns false if E matches, and true otherwise, you could use the =/= operator:

    delete_pkts(AcksList, State) ->
      NewSendingList = lists:filter(fun(X) ->
        lists:any(fun(E) -> E =/= X#internal_packet.message_number end, AcksList)
      end, State#state.pkt_send),
      State#state{ pkt_send = NewSendingList }.