Searching for an ets entry with a tuple as the key

I’ve been following a small tutorial around Registries and ETS Tables and i’m attempting to select an entry from a Registry.

{:ok, pid} = Registry.register(:user_registry, {:hello, :world}, "world")
fun = :ets.fun2ms(fn {product_id, product_name} = product when product_name == :hello -> product end)
Registry.select(:user_registry, fun)

This returns an error:

** (ArgumentError) invalid match specification in Registry.select/2: [{{:"$1", :"$2"}, [{:==, :"$2", :hello}], [:"$_"]}]
    (elixir 1.10.2) lib/registry.ex:1210: anonymous fn/3 in Registry.select/2
    (elixir 1.10.2) lib/enum.ex:2111: Enum."-reduce/3-lists^foldl/2-0-"/3
    (elixir 1.10.2) lib/registry.ex:1204: Registry.select/2

I’m not sure how to write the argument in such a way to search for tuple based keys and i think i need to do this so I can search for specific supervisors.

Strange as that matchspec works on an ETS table created in the shell and try to select on it.

Registry can have unexpected effects if you try use the special ets selector :"$_", which appears as a result of your fun2ms. https://hexdocs.pm/elixir/Registry.html#select/2 (section “do not use special match variables”)

Also, I think you’ll need a third bit in your select to match on the registry “value”.

concretely:

fn {{product_id, product_name}, _, _} when product_name == :hello -> {product_id, product_name} end
3 Likes

Answering my own question. It turns out that the select function demands a three tuple argument as the first parameter all the time in the form {key, pid, value}.

1 Like

yeah actually my fun is wrong, editing…

1 Like