I want to pattern match a map on a key when the second argument is a map with name
's value being the same as the key in the first argument's map.
Instead I get this:
8> c(room).
room.erl:23: variable 'PlayerName' is unbound
error
status({_Players, _Tables, ChallengerName}, #{name := ChallengerName}) ->
#{status => challenging};
status({#{PlayerName := PlayerStatus}, _, _}, #{name := PlayerName}) ->
PlayerStatus;
status(_, _) ->
#{status => null}.
Oddly, the first function declaration works fine where I pattern match an element in a tuple to a value in a map.
I found Pattern matching key in erlang maps - is there no way to pattern match on a key? What's the most efficient workaround?
I've hoped just changing the parameter order would work, but apparently not. So you need to pattern-match inside the body, after
Name
is bound:This is not an answer but rather a complement to Alexey answer.
As he does, I was thinking that changing the parameters order should be enough to solve your issue. I had in mind an execution model where the variables are bound during the pattern matching of each function head, from left to right. So if the
PlayerName
were bound in the first parameter match, it could be reused in the next variable as a map key to retrieve thePlayerStatus
.It does not work like this. In fact, using a variable twice in the function head like in
eq2(X,X) -> ...
is almost equivalent to add a guard condition like ineq1(Y,X) when Y =:= X -> ...
To illustrate this I wrote a minimal module with the version of code, compiled it and disassembled and commented the result. You will see that apart of an inversion of the parameter order for the comparison, the 2 codes are identical.Even with more complex function head, you can verify that the compiler works only by making test (comparison, type check, size...) on the function parameters or some term extract from the function parmeters.
Edit
Curiously, it could be done relatively easily, I have compiled the following code to assembler ( using the command
c(bar1,['S'])
):then modified the assembler file to:
re-compile the module from the assembler (
c(bar1,[from_asm]).
) and then, in the shell it works as expected (in this code I have reverted the order of the parameters for the modified functionstatus
compare tostatus1
from Alexey, but it was not necessary), I wonder if this kind of pattern matching will be available in a future release of the compiler?