I want to create a function which is able to return a list of a records field names. There are a set number of records in the project but defined in different modules. However at compile time they haven't been created yet.
print_record(Record) ->
[Name|Values] = tuple_to_list(Record),
case Name of
test_record_one ->
record_info(fields, test_record_one);
test_record_two ->
record_info(fields, test_record_two);
...
Else ->
Else
end.
The issue with this code is when compiling, the compiler returns with the records being undefined. This is true however I was wondering if there is a way to get around this.
I don't quite understand on what you mean by at compile time they haven't been created yet
, because record definition must be at least defined at compile time.
Let's say the record definition is defined in a header file (.hrl) which is accessible by your utility module.
%%Filename: records.hrl
-record(test_record_one, {field1, field2}).
-record(test_record_two, {field3, field4}).
And the utility module
-module(test_util).
-include("records.hrl"). %%assuming this hrl file is in the same directory, otherwise need to use include_lib directive
-export([print_record/1]).
-export([test_1/0]).
-export([test_2/0]).
print_record(Record) ->
[Name| Values] = tuple_to_list(Record),
case Name of
test_record_one -> record_info(fields, test_record_one);
test_record_two -> record_info(fields, test_record_two);
Else -> ok
end.
test_1() ->
test_util:print_record(#test_record_one{}).
test_2() ->
test_util:print_record(#test_record_two{field3 = "abc", field4 = 100}).
Testing directly from shell
%%Must inform Erlang shell on the record definition
> rd(test_record_one, {field1, field2}).
test_record_one
> rd(test_record_two, {field3, field4}).
test_record_two
> test_util:print_record(#test_record_one{}).
[field1,field2]
> test_util:print_record(#test_record_two{field3 = "abc", field4 = 100}).
[field3,field4]
Testing by calling the test functions
> test_util:test_1().
[field1,field2]
> test_util:test_2().
[field3,field4]