2010-07-22 16 views
6

J'ai écrit un module Erlang où toutes les fonctions internes ne sont pas directement appelées. Au lieu de cela, il y a un couple fonctionne qui ressemblent à ceci:Suppression des avertissements "fonction inutilisée" d'Erlang

weird_func(Cmd, Args) -> 
    ?MODULE:Cmd(Args). 

Il est un exemple simplifié, mais vous voyez l'idée. Le compilateur Erlang crache des avertissements sur les fonctions inutilisées, alors qu'en fait elles sont réellement utilisées, mais pas directement. Y a-t-il un moyen de supprimer ces avertissements? Idéalement, je ne veux pas supprimer tous ces avertissements, mais je voudrais plutôt dire au compilateur Erlang de considérer quelques fonctions spécifiques comme des cas spéciaux.

+2

appel d'une fonction de cette façon ne fonctionnera que si elle a été exportée. Vous êtes en train de lui faire un appel "externe" même si vous utilisez '? MODULE', qui est seulement une macro prédéfinie qui se développe dans le nom du module, et qui passe le nom de la fonction en argument. N.B. ce 'Args' sera une liste des arguments et la fonction appelée n'aura qu'un seul argument. – rvirding

Répondre

6

Si une fonction n'est ni exportée, ni explicitement appelée, elle est signalée comme inutilisée. Vous avez donc deux possibilités:

1) Exportez les fonctions utilisées indirectement. Si vous ne voulez pas que ces fonctions soient appelées à l'extérieur du module, vous pouvez indiquer dans les documents

2) Appel chaque fonction explicitement dans weird_func (et dans les commentaires.):

weird_func(fun1, [A1,A2]) -> 
    fun1(A1, A2); 
weird_func(fun2, []) -> 
    fun2(); 
weird_func(fun3, [A1,A2,A3]) -> 
    fun3(A1,A2,A3). 

Cette dernier est un peu plus verbeux, mais il fournira une meilleure erreur pour les utilisateurs, s'ils appellent une fonction inexistante

+1

Je suppose que 2) n'est pas une option lorsque vous utilisez {weird_result} -> spawn (? MODULE, fun1, [params]); – Daniel

11

Il ne s'agit pas seulement de supprimer l'avertissement. Une fonction non exportée ne peut pas être appelée comme vous le souhaitez.

-module(foo). 
-export([f/0]). 
f() -> ?MODULE:g(). 
g() -> ok. 

1> c(foo). 
./foo.erl:4: Warning: function g/0 is unused 
{ok,foo} 
2> foo:f(). 
** exception error: undefined function foo:g/0 

Le compilateur est libre de supprimer complètement la fonction inutilisée non exportée. Il suffit d'exporter la fonction rendant l'appel disponible en utilisant la syntaxe? MODULE: F.

2

Vous avez essentiellement deux options.

Le 1er est d'exporter les fonctions, en les "utilisant". Ceci est également nécessaire pour que votre exemple original fonctionne.

2 est d'appeler les fonctions localement en utilisant quelque chose comme: (.. Notez que mon exemple ne compile pas que vous devez diviser l'argument args en morceaux en fonction du Func que vous appelez)

weird_func(Cmd, Args) -> 
    case Cmd of 
     func1 -> func1(Arg1, Arg2, Arg3); 
     func2 -> func2(Arg1); 
     ... 

+0

Je pense que l'utilisation de la correspondance de formes est préférable dans ce cas: 'weird_func (func1, Args) -> ...; weird_func (func2, Args) -> ...; ' –

12

il y a une option de compilation spécifiquement pour cela:

http://www.erlang.org/doc/man/compile.html

donc, pour votre exemple annonce d'insertion IRECTIVE comme ceci:

-compile([{nowarn_unused_function, [{ wierd_function_1,Arity1 }, 
             ... ]}]). 

mais l'avertissement ci-dessus sur le compilateur jeter silencieusement les fonctions est toujours debout en autant que je sache.

1

Vous pouvez également passer Cmd dans le format fun func1/3, par exemple:

weird_func(fun func1/3, [1, 2, 3])

De cette façon, la fonction ne sera pas abandonnée.

Edit: juste ajouté mon commentaire il peut être utile pour les futurs lecteurs