Erlang: is there an equivalent to the C # preprocessor directive ##?

Is there an equivalent to the C ## preprocessor directive in Erlang?

Suppose I want to combine two atoms () using the -define preprocessor directive, how would I do this without having side effects at runtime?

+3
source share
6 answers

You can get a fairly close result using parsing conversions. The following parse_transform searches for "atom1 ++ atom2" and converts it to "atom1atom2" at compile time.

Module example

-module(z).

-export([z/0]).

-compile({parse_transform, zt}).

z() -> concat ++ enate.

compilation with 'S' proves that it really was merged at compile time:

{function, z, 0, 2}.
  {label,1}.
    {func_info,{atom,z},{atom,z},0}.
  {label,2}.
    {move,{atom,concatenate},{x,0}}.
    return. 

works as expected:

1> z:z().
concatenate

, :

-module(zt).

-export([parse_transform/2]).

parse_transform(AST, _Options) ->
  [parse(T) || T <- AST].

parse({function, _, _, _, _} = T) ->
  erl_syntax_lib:map(fun hashhash/1, T);
parse(T) -> T.

hashhash(Tree) ->
  erl_syntax:revert(
    case erl_syntax:type(Tree) of
      infix_expr ->
        Op = erl_syntax:infix_expr_operator(Tree),
        Left = erl_syntax:infix_expr_left(Tree),
        Right = erl_syntax:infix_expr_right(Tree),
        case {erl_syntax:operator_name(Op), erl_syntax:type(Left), erl_syntax:type(Right)} of
          {'++', atom, atom} ->
            erl_syntax:atom(erl_syntax:atom_literal(Left) ++ erl_syntax:atom_literal(Right));
          _ ->
            Tree
        end;
      _ ->
        Tree
    end
  ).

EDIT: "" infix ++. "##".

+4

, , , .

-define(CATATOM(A, B), list_to_atom(list:concat(atom_to_list(A), atom_to_list(B)))).
AtomA = atom1.
AtomB = atom2.
NewAtom = ?CATATOM(AtomA, AtomB). % NewAtom is atom1atom2

, , ?

-define(CATATOM(A, B), AB).
NewAtom = ?CATATOM(atom1, atom2). % NewAtom is atom1atom2

, . atom1atom2 .

. , - 3 .

+1

, , , . . , .

, Arg, . .

, , ? , , .

+1

, . , - .

0

There is a concept of syntactic transformations that would allow atoms to be combined at compile time.

0
source

You mentioned in one of your answers that you want to parameterize modules - this can be done at runtime ...

An academic article about it here .

Mochiweb uses it.

0
source

Source: https://habr.com/ru/post/1717677/


All Articles