Shorthand For Updating a Key On a Map In a Record?

I’ve got a record with a map that I’d like to add a key to. I have a way to do it but it’s pretty long-winded and not as convenient as the M#{K=>V} syntax for maps not in a record.

-module(records2).
-export([make_stuff/0, put_map/3, put_m1/3, put_m2/3]).
%%-export([put_mX1/3, put_mX2/3, put_mX3/3]).

-record(stuff, {
  m=maps:new()
}).

%% This updates Map
put_map(Key, Value, Map=#{}) ->
  Map#{Key => Value}.

%% This clears other keys on m on stuff
put_m1(Key, Value, Stuff=#stuff{}) ->
  Stuff#stuff{m = #{Key => Value}}.

%% This adds a key to m on stuff
put_m2(Key, Value, Stuff=#stuff{}) ->
  Stuff#stuff{m = maps:put(Key, Value, Stuff#stuff.m)}.

%% These are invalid:
%%put_mX1(Key, Value, Stuff=#stuff{}) ->
%%  Stuff#stuff{m#{Key => Value}}.
%%
%%put_mX2(Key, Value, Stuff=#stuff{}) ->
%%  Stuff#stuff{m=m#{Key => Value}}.
%%
%%put_mX3(Key, Value, Stuff=#stuff{}) ->
%%  Stuff#stuff.m#{Key => Value}.

make_stuff() ->
  #stuff{}.

I’m wanting the call to records2:put_mX("Foo", "Bar", records2:put_mX("Fizz", "Buzz", records2:make_stuff())). to return #state{m={"Foo": "Bar", "Fizz": "Buzz"}}. and not #state{m={"Foo": "Bar"}}.

As you can see I tried some different things here but they weren’t valid.

Is there any shorthand for updating a key on a map in a record or is the put_m2 function I have here the only way?

4 Likes

There’s no specific shorthand for that, but this ought to do what you want:

foo(Key, Value, #stuff{m=Map}=Stuff) ->
  Stuff#stuff{m=Map#{ Key => Value }}.
5 Likes

how about

put_m2(Key, Value, #stuff{m = M} = Stuff) ->
  Stuff#stuff{m = M#{Key => Value}}.

edit: @jhogberg wins the race

4 Likes

Ah much nicer. Thank you.

3 Likes