2015-03-03 8 views
5

Mi piacerebbe fare una funzione in Elixir 1.0.3 fare riferimento a una variabile all'interno del suo ambito "padre". In questo caso, il suo ambito genitore è un modulo.Come posso fare riferimento a una variabile del modulo in una funzione senza fare riferimento al suo modulo in Elixir 1.0.3? Nell'ambito genitoriale?

Ecco lo stesso codice di quello che ho usato nella mia ultima domanda:

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 

Se cambio al seguente:

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 

Compila bene, ma ottengo il seguente errore se provo la funzione msgurr:

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

ho anche provato il seguente:

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 

ottengo una fase di compilazione avvertimenti qui, però: ➜ elixirc ubuntu recursiontest.exs recursion_and_import_test.exs: 1: avvertimento: ridefinendo modulo Rec recursion_and_import_test.exs: 2: avvertimento: contatore variabile è inutilizzato recursion_and_import_test.exs: 4: avvertimento: non utilizzato import Rec

Quando tento di usare la funzione msgurr:

➜ ubuntu iex Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp: 8: 8] [async-t hreads: 10] [kernel-poll: falsi]

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 

mi sembra di essere in grado di importare una variabile della mia da un modulo in una funzione all'interno di quel modulo.

Ho esaminato la documentazione di importazione, ma non riesco a dare molto senso a come fare questo genere di cose. Devo controllare i documenti di Erlang?

risposta

4

Si confondono i moduli con gli oggetti.

Rec.counter 

Fa sempre riferimento alla funzione all'interno del modulo di registrazione. Questo è quello che ti dicono i messaggi di errore, non riescono a trovare la funzione. I moduli non possono avere variabili nel modo in cui stai pensando a loro.

I moduli possono avere attributi. Mentre potrebbe essere possibile fondere vuoi che tu voglia con un attributo di modulo, dovresti semplicemente creare una funzione che restituisca una costante se vuoi fare un riferimento usando Rec.counter.

def counter do 
    "done!" 
end 

C'è di più sul modulo attributi here, ma se si vuole essere in grado di pensare in elisir, è necessario iniziare a pensare "funzioni non variabili".

+0

A proposito, perché non consentire solo variabili anziché attributi? Mi manca esperienza con qualsiasi tipo di programmazione funzionale. Sembra un po 'arbitrario per me, anche se so che ci deve essere una ragione. –

+2

Le variabili del modulo implicano uno stato mutabile, che rompe uno dei principi della programmazione funzionale. C'è molto di più di quello che posso inserire in un commento. Potresti trovare utile questa discussione https://groups.google.com/forum/?hl=it#!topic/elixir-lang-talk/jvl9THiFFEI –

+2

È anche possibile evitare cose come 'local' in Python, dove si potrebbero avere conflitti tra la" variabile del modulo "e la funzione uno. Rimuovere l'ambiguità e introdurre una notazione esplicita è più pulito perché segnala l'intento (ad esempio, si usa un @attribute perché da qualche parte ne avrete bisogno). –

Problemi correlati