I have a function that maintains some values as state for its recursion and in order to be flexible with the order of its arguments, I am using a Map
to store the state and pass it around between calls.
My base case is that the function gets called without a socket
, so there should be a case where only that setup is done. However, I can't find a way to match a non-existing key of a Map
.
Attempts:
def measure(args = %{socket: nil}) ...
def measure(args = %{socket: socket}) when not is_port(socket) ...
However, these patterns only match when there exists a key socket
that is nil
/not a port.
Is there a way of specifying a pattern that does match a non-existing key? Or do I have to create another entry function that provides default values for my Map?
With Elixir version 1.10.0 there is a new guard intruduced called is_map_key
(https://hexdocs.pm/elixir/Kernel.html#is_map_key/2)
You can now handle non existing keys in maps like:
def measure(args) when not is_map_key(args, :socket) do
handle_without_socket(args)
end
def measure(args = %{socket: socket}) do
handle_socket(socket, args)
end
You need a clause that matches on any value for that and add another one after:
def measure(args = %{socket: socket}) do
handle_socket(socket, args)
end
def measure(args) do
handle_without_socket(args)
end
Generally speaking, the preferred way of using maps is via the strict syntax. You would just match on :socket
or call args.socket
and it will fail if a socket is not available as key.
If you are passing optional data, maybe you want to use a keyword list instead of a map.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With