Using put_in for structs

I have declared a struct which contains some maps, via something like:

defstruct [
    x: %{},
    y: %{},
    z: %{}
  ]

I am trying to expose some functions to facilitate updating values in these maps, but when I try to use put_in, I get an error because it doesn’t work for structs.

put_in(%MyStruct{}, [:some, "path"], "value")
** (UndefinedFunctionError) function MyStruct.get_and_update/3 is undefined (MyStruct does not implement the Access behaviour)

Is there a way to add some functions to the struct so it could “inherit” the functionality from Map ? I tried adding this to my struct module:

defdelegate get_and_update, to: Map, as: :get_and_update

but that didn’t seem to have any effect.

1 Like

Access implementations were broken/removed quite a while ago, so you can’t use map-based syntax, rather you need to use key/dotted syntax. I.E. instead of put_in(%MyStruct{}, [:some, "path"], "value") you’d do put_in(%MyStruct{}, [Access.key(some), "path"], "value"), or more shortly: put_in(%MyStruct{}.some["path"], "value")

7 Likes