[erlang-questions] code_change for gen_fsm: how to actually handle a state change

Richard Carlsson carlsson.richard@REDACTED
Tue Nov 22 11:35:59 CET 2011


On 11/22/2011 08:40 AM, Bengt Kleberg wrote:
>
> Is it correct to say that the old definition of #state{} is
> -record(state, {item1, item2}).
> and that the new is
> -record(state, {item1, item2, newfield}).
>
> I think you will find it difficult to get both these records to work in
> the same file at the same time (during code change).


Possible solution: let code_change call a separate module that 
transforms the old definition to an intermediate format that the gen_fsm 
module can use to initialize the new state. That way, the different 
record declarations are never present in the same module.

code_change(#state{}=State) ->
     State;  % already the new state
code_change(OldState) ->
     init_state(state_converter:old_to_proplist(OldState)).

init_state([{foo, Foo} | Ps], State) ->
     init_state(Ps, State#state{foo=Foo});
...
init_state([], State) ->
     State.

A more quick-and-dirty solution is to re-tag the old state so you can 
use it with a different state declaration:

-record(old_state, {item1, item2}).
-record(state, {item1, item2, newfield}).

code_change(#state{}=State) ->
     State;  % already the new state
code_change(OldState) ->
     update_state(setelement(1, State, 'old_state'), #state{}).

update_state(OldState, State) ->
     State#state{item1 = OldState#old_state.item1,
                 item2 = OldState#old_state.item2,
                 newfield = 42}.


     /Richard



More information about the erlang-questions mailing list