Search code examples
stringerlang

How to convert an Erlang record from string representation back to a record?


The following allows to convert a tuple or object back to an object in erlang:

{ok, Tokens, _} = erl_scan:string("{'abc',123}."),
{ok, X} = erl_parse:parse_term(Tokens).

But when you have a record represented as a string, such as:

-record(myrecord,{firstname,lastname,age}).
...
RecString = "#myrecord{firstname='john',lastname='doe',age=22}.",
{ok, Tokens, _} = erl_scan:string(RecString),
{ok, X} = erl_parse:parse_term(Tokens).

... the above will fail with the message:

** exception error: no match of right hand side value {error,{1,erl_parse,["syntax error before: ",[]]}}

Thoughts on how to achieve that? Thanks.


Solution

  • First you must remember that a record does not exist as a data-type, internally records are tuples where the first element is the name of the record. So with your record definition:

    -record(myrecord,{firstname,lastname,age}).
    

    the creating the record with

    #myrecord{firstname='john',lastname='doe',age=22}
    

    would result in the tuple

    {myrecord,john,doe,22}
    

    which just contains the actual data. This is how records are defined, see here.

    Second point is that records are purely compile-time syntactic constructions which compiler transforms in tuple operations. So the definition of a record does not exist as such as data anywhere. Only the compiler knows of record definitions. So when you print a record all you see is the tuple. However you can define record inside the shell so you can use record syntax in the shell, see in the shell documentation.

    So in this sense you cannot really convert a record to/from its string representation. You can parse the string but this only returns the abstract syntax which is not what you are after. They are expressions so you need to end the string with a . and use erl_parse:exprs/1.

    Hope this helps. What are you trying to do? Or rather why are you trying to do it?