目的

  • 将多个模块中的函数使用同一模块调用
  • 实现类似面向对象继承/重载逻辑
  • 瞎折腾

    1
    2
    3
    例如:
    存在`util_lists`, `util_time` 等模块
    使用统一接口`util:func/x`调用, 无需知道`func`具体在哪个模块

前提

需要加载的模块需要先编译

使用

1
2
3
4
5
6
-compile([{parse_transform, func_merge_runtime}]).

%% 加载a模块的所有导出函数
-load_all(a).
%% 加载a:f1/0,a:f2/1函数
-load_func({a, [f1/0, f2/1]}).

例子

目录结构

erl文件
func_merge_runtime.erl Parse transform
func_a.erl 模块a
func_b.erl 模块b
func_merge.erl 合并文件
Emakefile emakefile
readme.md readme
1
2
3
4
5
6
7
8
9
10
$ tree
.
├── ebin
├── Emakefile
├── readme.md
└── src
├── func_a.erl
├── func_b.erl
├── func_merge.erl
└── func_merge_runtime.erl

编译

1
2
3
4
5
6
7
8
9
10
11
$erl -pa ebin -make

Recompile: src/func_a
Recompile: src/func_b
Recompile: src/func_merge_runtime
Recompile: src/func_merge
Warning: func_b:a/0 function duplicate, Used: a/0 -> func_a:a/0
Warning: func_b:b/0 function duplicate, Used: b/0 -> func_a:b/0
Warning: func_a:a/0 function duplicate, Used: a/0 -> func_a:a/0
Warning: func_a:b/0 function duplicate, Used: b/0 -> func_a:b/0
Warning: a/0 overloaded ...

运行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Eshell V6.3  (abort with ^G)
1> func_merge:module_info().
[{exports,[{a,1},
{a,2},
{a,0},
{b,0},
{c,0},
{d,0},
{module_info,0},
{module_info,1}]},
{imports,[]},
{attributes,[{vsn,[51615201590186967477100822039580749453]}]},
{compile,[{options,[error_summary,debug_info,
{outdir,"./ebin"}]},
{version,"5.0.3"},
{time,{2018,9,13,3,14,3}},
{source,"e:/zzzz/src/func_merge.erl"}]}]
2> func_merge:a().
func_merge_a
3> func_merge:b().
func_a_b
4> func_merge:c().
func_b_c
5> func_merge:d().
func_b_d
6> func_merge:a(1).
func_merge_a1
7> func_merge:a(2).
func_merge_a2
8> func_merge:a(c).
func_merge_a3
9>

问题

在修改func_a,func_b模块后,func_merge不会重新编译
要手动删除重新编译