Is it possible to use record name as a parameter?

You can't use the record syntax if you don't have access to the record during compile time.

But because records are simply transformed into tuples during compilation it is really easy to construct them manually:

-record(some_rec, {a, b}).

make_record(Rec, Values) ->
    list_to_tuple([Rec | Values]).

test() ->
    R = make_record(some_rec, ["Hej", 5]),  % Dynamically create record
    #some_rec{a = A, b = B} = R,            % Access it using record syntax
    io:format("a = ~p, b = ~p~n", [A, B]).  

Alternative solution

Or, if you at compile time make a list of all records that the function should be able to construct, you can use the field names also:

%% List of record info created with record_info macro during compile time
-define(recs, 
    [
     {some_rec, record_info(fields, some_rec)},
     {some_other_rec, record_info(fields, some_other_rec)}
    ]).

make_record_2(Rec, Fields, Values) ->
    ValueDict = lists:zip(Fields, Values),

    % Look up the record name and fields in record list
    Body = lists:map(
         fun(Field) -> proplists:get_value(Field, ValueDict, undefined) end,
         proplists:get_value(Rec, ?recs)),

    list_to_tuple([Rec | Body]).

test_2() ->
    R = make_record_2(some_rec, [b, a], ["B value", "A value"]),
    #some_rec{a = A, b = B} = R,
    io:format("a = ~p, b = ~p~n", [A, B]).

With the second version you can also do some verification to make sure you are using the right fields etc.

Other tips

Other useful constructs to keep in mind when working with records dynamically is the #some_rec.a expression which evaluates to the index of the a field in some_recs, and the element(N, Tuple) function which given a tuple and an index returns the element in that index.


This is not possible, as records are compile-time only structures. At compilation they are converted into tuples. Thus the compiler needs to know the name of the record, so you cannot use a variable.

You could also use some parse-transform magic (see exprecs) to create record constructors and accessors, but this design seems to go in the wrong direction. If you need to dynamically create record-like things, you can use some structures instead, like key-value lists, or dicts.

Tags:

Erlang