2015-03-03 3 views
5

Ich möchte eine Funktion in Elixir 1.0.3 beziehen sich auf eine Variable innerhalb seiner "übergeordneten" Bereich. In diesem Fall ist der übergeordnete Bereich ein Modul.Wie kann ich auf eine Modulvariable in einer Funktion verweisen, ohne auf ihr Modul in Elixir 1.0.3 Bezug zu nehmen? In seinem übergeordneten Bereich?

Hier ist der gleiche Code wie das, was ich in meiner letzten Frage verwendet:

defmodule Rec do 
    def msgurr(text, n) when n <= 1 do 
    IO.puts text 
    end 

    def msgurr(text, n) do 
    IO.puts text 
    msgurr(text, n - 1) 
    end 
end 

Wenn ich es wie folgt ändern:

defmodule Rec do 
    counter = "done!" 
    def msgurr(text, n) when n <= 1 do 
    IO.puts text 
    IO.puts Rec.counter 
    end 

    def msgurr(text, n) do 
    IO.puts text 
    msgurr(text, n - 1) 
    end 
end 

Es kompiliert ganz gut, aber ich bekomme die folgende Fehler, wenn ich die msgurr Funktion versuchen:

** (UndefinedFunctionError) undefined function: Rec.counter/0 
    Rec.counter() 
    recursion_and_import_test.exs:5: Rec.msgurr/2 

ich habe auch versucht die folgenden:

defmodule Rec do 
    counter = "done!" 
    def msgurr(text, n) when n <= 1 do 
    import Rec 
    IO.puts text 
    IO.puts Rec.counter 
    end 

    def msgurr(text, n) do 
    IO.puts text 
    msgurr(text, n - 1) 
    end 
end 

ich einen Compiler-Warnungen hier, aber: ➜ ubuntu elixirc recursiontest.exs recursion_and_import_test.exs: 1: Warnung: Neudefinition Modul Rec recursion_and_import_test.exs: 2: Warnung: Variable Zähler wird nicht verwendet recursion_and_import_test.exs: 4: Warnung: nicht verwendeten Import Rec

Wenn ich versuche, die msgurr Funktion zu verwenden:

➜ ubuntu iex Erlang/OTP 17 [erts-6.3] [Quelle] [64-bit] [smp: 8: 8] [async-t hreads: 10] [kernel-Umfrage: false]

Interactive Elixir (1.0.3) - press Ctrl+C to exit (type h() ENTER for help) 
iex(1)> import Rec 
nil 
iex(2)> Rec.msgurr("blah", 3) 
blah 
blah 
blah 
** (UndefinedFunctionError) undefined function: Rec.counter/0 
    Rec.counter() 
    recursiontest.exs:6: Rec.msgurr/2 

Ich scheine eine Variable meines eigenen aus einem Modul in eine Funktion zu sein, nicht in der Lage innerhalb dieses Modul zu importieren.

Ich bin über die Importdokumentation gegangen, aber ich kann nicht viel Sinn daraus machen, wie man so etwas macht. Soll ich die Erlang-Dokumente überprüfen?

Antwort

4

Sie verwirren Module mit Objekten.

Rec.counter 

Bezieht sich immer auf die Funktion im Rec Modul. Das ist was die Fehlermeldungen Ihnen sagen, sie können die Funktion nicht finden. Module können keine Variablen in der Art haben, wie Sie an sie denken.

Module können Attribute haben. Während es möglich sein könnte, wollen Sie mit einem Modul-Attribut wollen, sollten Sie nur eine Funktion, die eine Konstante zurückgibt, wenn Sie es mit Rec.counter verweisen möchten.

def counter do 
    "done!" 
end 

Es gibt mehr auf Modul-Attribute here, aber wenn man in Elixier zu denken in der Lage sein wollen, müssen Sie beginnen „Funktionen nicht Variablen“ zu denken.

+0

Apropos, warum nicht nur Variablen anstelle von Attributen zulassen? Ich habe keine Erfahrung mit irgendeiner Art von funktionaler Programmierung. Es scheint mir irgendwie willkürlich, obwohl ich weiß, dass es einen Grund geben muss. –

+2

Modulvariablen würden einen veränderlichen Zustand implizieren, der einen der Grundsätze der funktionalen Programmierung durchbricht. Es gibt viel mehr als das, worauf ich in einem Kommentar eingehen kann. Sie finden diesen Thread möglicherweise nützlich https://groups.google.com/forum/?hl=de#!topic/elixir-lang-talk/jvl9THiFFEI –

+2

Es ist auch zu vermeiden, Dinge wie "local" in Python, wo Sie Konflikte zwischen der "Modul-Variable" und der Funktion haben könnte. Das Entfernen der Mehrdeutigkeit und das Einfügen einer expliziten Notation ist sauberer, da es die Absicht signalisiert (d. H. Sie verwenden ein @ Attribut, weil Sie es irgendwo benötigen). –

Verwandte Themen