2017-02-09 1 views
0

Ich mag eine schwere Berechnung für ein Modul konstant in eine separate Funktion setzen, aber dies nicht gelingt:berechnet Modul konstant in einer Funktion

defmodule Test do 
    @test calc_constant() 

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

Kann ich irgendwie das tun, ohne die gesamte Berechnung schreiben an die Oberseite meines Moduls?

Antwort

2

Ja, Sie können, aber Sie sollten die Funktion innerhalb anderen Modul setzen.

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 

Der Grund dafür ist: @var Erklärungen vollständig auf Kompilierungsphase erweitert werden. Während Sie die Funktion im selben Modul haben, erleben Sie ein Hühnerei-Problem.


Nebenbei bemerkt: wenn man viele Konstanten zu erklären hat, umgekehrt wäre, ein Modul zur Verfügung zu stellen, die __using__ Makro- und Kernel.use/2 es in Ihrem Modul wie folgt erklärt:

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 
Verwandte Themen