yrashk edited this page Sep 13, 2010 · 5 revisions
Clone this wiki locally

WARNING: This software is pre-release quality. Some things will probably fail and overall code quality is pretty poor, but you can use it for experiments. This code will be improved since it is going to be used in a largeish Erlang project.

There are some bugs I am aware of. They are going to be fixed.

I admit that this documentation sucks. I only spent 10 minutes writing it. It will be fixed, too.


Recmod is a simple parse transformation that allows you to use records as modules. It is somewhat close to Erlang’s hidden feature called “parametrized modules”, just done a little bit differently.

In order to use, all you need is to create a module named the same way your record is named and specify this attribute:

-compile({parse_transform, recmod}).

Needless to say, you need to include your record definition into your module (either directly or through -include() or -include_lib() attribute).

Recmod (i.e. a record module) will automatically create a parametrized module with all record fields as parameters, and some extra automatically created functions.

Each function that you defined in your recmod, will automatically receive special variables SELF and THIS (SELF is either equal to THIS or to extension record if this is a call coming from derived recmods; THIS is a current recmod). It will also receive all record fields camelized (i.e. this_field converts to ThisField).

Special automatically defined functions are:

new() → will create a default recmod
record_fields() → will return a list of fields
field1(), this_field() → readers of each record field

You can also define some functions ‘static’ by specifying them in a -static() attribute.

So how can you use it? You can, for example, do stuff like:

User = read_user_record_from_mnesia(),
io:format("User name: ~s~p", [User:name()]), % instead of io:format("User name: ~s~p", [User#user.name])
User1 = User:mark_deleted(),
% ...

Feel free to email me at yrashk@gmail.com if you have any further questions (or just read the code ;)


Q: Does it support inheritance?
A: Yes, pretty much, you can specify base recmod using standard -extends() attribute. It will transparently coerce your extension record to base record using similar record field names; or you can define your own to_base() function. What’s really nice about they way it works is that if none of your function clauses match, it will try to redirect your call to the base module (unlike in usual parametrized modules).


You can start with code as simple as this:

-compile({parse_transform, recmod}).
	 field3 = "default"

somefun() ->