All the erlang books seem to say export_all is bad practice but don't give a reason. In the end most modules spend a majority of their time with compile(export_all) because constantly updating the list of modules to remove the helper functions is a hassle. Is it bad practice because I'm supposed to care about the functions I expose to other developers? Or is it bad practice because there's some kind of performance cost in the number of functions a module has, because of maybe things like hot code loading. If there is a performance hit to stuffing a module with a lot of functions, how bad is it?
问题:
回答1:
For several reasons:
Clarity: it's easier to see which functions are intended to be used outside the module.
When you tab complete in the Erlang shell you get a list of only the exported functions and no others. When you refactor the module, you know which functions you can safely rename without external users depending on them.
Code smell: you get warnings for unused functions.
Therefore you'll avoid dead code.
Optimization: the compiler might be able to make more aggressive optimizations knowing that not all functions have to be exported.
回答2:
While I don't know for sure if there are any practical performance implications of using -compile(export_all).
, I doubt they are significant enough to care.
However, there a benefit of declaring the list of exports explicitly. By doing this, everyone can figure out the interface of the module by looking at the first page of the .erl
file. Also, as with many other things that we tend to write down, explicit declaration of the module interface helps to maintain its clarity.
With that said, when I start working on a new Erlang module I always type -module(...). -compile(export_all).
After the interface becomes mature enough I add an explicit -export([...])
while keeping the export_all
compile option.
回答3:
Having a defined list of which functions are external, and therefore which ones are internal, is extremely useful for anyone who will work on your code in the future. I've recently been refactoring some old code, and the use of export_all in most of the modules has been a continual source of annoyance.