2017-02-09 91 views
0

我想提出一個沉重的計算模塊固定到一個單獨的功能,但這種失敗:計算模塊中的功能不斷

defmodule Test do 
    @test calc_constant() 

    defp calc_constant do 
    # Calculation heavy task like building a translation table 
    end 
end 

我能以某種方式做到這一點,而無需編寫整個計算在我的模塊的頂部?

回答

2

是的,你可以,但你應該把功能放在其他模塊。

iex(1)> defmodule A, do: def calc, do: 42 
{:module, A, <<70, 79, ...>>, {:calc, 0}} 

iex(2)> defmodule B do 
...(2)> @a A.calc() 
...(2)> def a, do: @a 
...(2)> end 
{:module, B, <<70, 79, ...>>, {:a, 0}} 

iex(3)> B.a 
42 

的原因是:@var聲明是在編譯階段被完全展開。在同一模塊內部具有該功能時,您會遇到雞蛋問題。


旁註:如果一個人有很多常量申報,倒過來是提供一個模塊,聲明__using__宏觀和Kernel.use/2它你的模塊中是這樣的:

defmodule HeavyConstants do 
    defmacro __using__(_opts) do 
    quote bind_quoted: [test1: heavy_calc1(), ...] do 
     @test1 test1 
     @test2 test2 
     ... 
     @testN testN 
    end 
    end 
end 

defmodule Test do 
    use HeavyConstants 

    # here you have all `N` `@test{1,2,...N}` on hand 
end