[erlang-questions] useful trick for finding record instantiations

Michael Turner michael.eugene.turner@REDACTED
Fri Apr 27 16:14:38 CEST 2012


Where were you last week, when I needed this hack? ;-)

-michael turner

On Fri, Apr 27, 2012 at 10:06 PM, Richard Carlsson
<carlsson.richard@REDACTED> wrote:
> It's not unusual when working with some legacy code that you want to find
> all the locations that instantiate a certain record using the #foo{...}
> syntax, so that you can replace those with calls to a function that controls
> the instantiation for better encapsulation:
>
>  init_foo(...) -> #foo{...}.
>
> However, you can't easily grep for '#foo{' because of all the patterns that
> have the same syntax, '= #foo{' misses cases where a record is instantiated
> as the argument of a function call, and so on. It's hard to know that you've
> found all the occurrences.
>
> This little trick works pretty well, though: you add a dummy field to the
> record definition (usually in a header file):
>
>  -record(foo, {'$hidden' = 1/0,
>                ...}).
>
> This will not cause errors or warnings at the point of the record
> declaration, so modules that include the header file and just use the record
> for pattern matching and field accesses will compile cleanly. But
> instantiations of the record, such as 'X=#foo{...}', will cause the compiler
> to warn that "this expression will fail with a 'badarith' exception". Only
> instantiations that override this locally will not trigger the warning.
> Since you just added that field, there should not be any cases like that in
> the code, apart from the one you write in your new instantiator function:
>
>  init_foo(...) -> #foo{'$hidden'=[], ...}.
>
> The exception is that if you have a record instantiation on the form
> '#foo{..., _=Default}', which overrides the default setting for all fields
> not explicitly mentioned (usually only used in match specs). You can use
> this to suppress the warning in places like unit tests where you might want
> to allow direct instantiation.
>
> Of course, once you're done refactoring and have all instantiations under
> control, you remove the dummy field again (in particular if it's used for a
> mnesia table).
>
> Have a nice weekend,
>
>    /Richard
> _______________________________________________
> erlang-questions mailing list
> erlang-questions@REDACTED
> http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list