[erlang-questions] Using -callback with libraries supporting R14 and higher

Fred Hebert mononcqc@REDACTED
Tue Feb 19 18:30:16 CET 2013


Argh, disregard the entire parse transform idea.

I had forgotten that versions of Erlang prior to R15 didn't actually
support the syntax required for -callback arguments. The code that uses
them will still fail there, before the parse transform can run.

My bad,
Fred.

On 02/19, Fred Hebert wrote:
> First of all, you shouldn't use the OTP version to define your macros --
> this is a release name, and it likely will change with custom releases.
> 
> You can detect compiler or kernel versions easily if what you want to do
> is define macros. Just make a quick call to:
> 
> erl -noshell  -eval 'io:format("~s~n",[element(3, lists:keyfind(kernel,1,application:which_applications()))]),init:stop().'
> 
> This will tend to break when you don't control how to build the library,
> though.
> 
> At this point what you might want to do is use a parse transform
> that will do the call at compile time to determine what version of the
> compiler is being used right now, and filter out the attributes you do
> not want to keep.
> 
> I've written a quick one that seems to work (didn't test it
> extensively). Based on the current ERTS version, it will either drop the
> behaviour_info/1 and behavior_info/1 functions (and remove them from the
> export lists), or remove the -spec arguments. The script is also visible
> at https://gist.github.com/ferd/4987814, and if people are interested,
> I'll make it a minimal library application available from my github
> account so people can use it with rebar or whatever dependency
> management system they have:
> 
> -module(behaviour_parse).
> -export([parse_transform/2]).
> -define(CUTOFF, "2.15"). % R15B
> 
> parse_transform(AST, _Opts) ->
>     [Vsn] = [X || {kernel,_,X} <- application:which_applications()],
>     walk_ast(if Vsn >= ?CUTOFF -> spec;
>                 Vsn < ?CUTOFF -> func
>              end,
>              AST).
> 
> walk_ast(_, []) ->
>     [];
> walk_ast(func, [{attribute, _Ln, callback, _}|T]) ->
>     walk_ast(func, T);
> walk_ast(spec, [{attribute, Ln, export, List}|T]) ->
>     [{attribute, Ln, export, List -- [{behaviour_info,1},{behavior_info,1}]}
>      | walk_ast(spec, T)];
> walk_ast(spec, [{function, _Ln, behaviour_info,1,_Clauses}|T]) ->
>     walk_ast(spec, T);
> walk_ast(spec, [{function, _Ln, behavior_info,1,_Clauses}|T]) ->
>     walk_ast(spec, T);
> walk_ast(Type, [H|T]) ->
>     [H|walk_ast(Type, T)].
> 
> 
> Just include it in a file with:
> 
> -compile({parse_transform, behaviour_parse}).
> 
> And it should do its thing.
> 
> Regards,
> Fred.
> 
> On 02/19, Anthony Molinaro wrote:
> > Hi,
> > 
> > I recently was asked to add -callback support to a library I maintain
> > because someone was getting warnings from dialyzer.  Upon looking into
> > it I don't see any way to support both R14 and R15.
> > 
> > The -callback attribute seems to cause syntax errors with the R14 compiler.
> > If you include both with R15 you get an error about how you can't use them
> > together.
> > 
> > I know it's possible using a -D flag and some conditional macros, but that
> > requires integration with the build system (and despite its wide appeal,
> > rebar is not the only game in town, some people use EMakefiles, some
> > GNU autotools, etc).
> > 
> > Does OTP provide some sort of macro definition, similar to say ?MODULE
> > which provides the version of OTP?  If not how are other library
> > maintainers providing versions for multiple incompatible OTP releases?
> > 
> > -Anthony
> > 
> > -- 
> > ------------------------------------------------------------------------
> > Anthony Molinaro                           <anthonym@REDACTED>
> > _______________________________________________
> > erlang-questions mailing list
> > erlang-questions@REDACTED
> > http://erlang.org/mailman/listinfo/erlang-questions



More information about the erlang-questions mailing list