2016-05-13 6 views
3

Ich habe ein Modul ich hier schrieb:Wie in julia benutzerdefinierten Modul importieren

# Hello.jl 
module Hello 
    function foo 
     return 1 
    end 
end 

und

# Main.jl 
using Hello 
foo() 

Wenn ich laufen die Main Modul:

$ julia ./Main.jl 

ich das bekommen Fehler:

ERROR: LoadError: ArgumentError: Hello not found in path 
in require at ./loading.jl:249 
in include at ./boot.jl:261 
in include_from_node1 at ./loading.jl:320 
in process_options at ./client.jl:280 
in _start at ./client.jl:378 
while loading /Main.jl, in expression starting on line 1 

Antwort

6

Sie sollten include("./Hello.jl") vor using Hello

+3

Was ist die Bedeutung von 'using' dann? Ich dachte, dass diese kw würde das Modul für mich enthalten ... – dopatraman

+0

@doptraman 'using' ist, um die Namen eines Moduls in den aktuellen Bereich einzuführen, während das Modul selbst' include() 'automatisch (außer für die in "LOAD_PATH") –

+0

Wenn Sie Definitionen in einem 'Modul' haben, müssen Sie diese auch exportieren. – m33lky

0

Wenn Sie Funktion foo zuzugreifen, wenn das Modul Import mit „mit“ Sie „Export foo“ in der Kopfzeile des Moduls hinzufügen müssen.

0

Wenn Sie die Datei nicht explizit laden (include("./Hello.jl")), sucht Julia nach Moduldateien in Verzeichnissen, die in der Variablen LOAD_PATH definiert sind.

Siehe this page.

6

Es gab schon einige kurze Antworten, aber ich wollte, wenn möglich, eine vollständigere Antwort geben.

Wenn Sie using MyModule ausführen, sucht Julia nur in einer Liste der Verzeichnisse, die als LOAD_PATH bekannt sind.

2-element Array{ByteString,1}: 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4" 

Dies sind die Verzeichnisse, die Julia für Module suchen zu schließen, wenn Sie using Hello geben: Wenn Sie LOAD_PATH in der Julia REPL eingeben, werden Sie so etwas wie die folgenden erhalten. In dem Beispiel, das Sie angegeben haben, konnte Julia, da Hello nicht in Ihrem LOAD_PATH war, es nicht finden.

Wenn Sie ein lokales Modul einbeziehen möchten, können Sie dessen Position relativ zu Ihrem aktuellen Arbeitsverzeichnis angeben.

julia> include("./src/Hello.jl") 

Sobald die Datei aufgenommen wurde, können Sie dann using Hello als normal laufen alle vom gleichen Verhalten zu bekommen. Für einmalige Skripts ist dies wahrscheinlich die beste Lösung. Wenn Sie jedoch regelmäßig include() einen bestimmten Satz von Verzeichnissen finden, können Sie sie dauerhaft zu Ihrem LOAD_PATH hinzufügen.

Hinzufügen von Verzeichnissen LOAD_PATH

manuell hinzufügen Verzeichnisse zu Ihrem LOAD_PATH kann ein Schmerz, wenn Sie regelmäßig auf bestimmte Module verwenden, die außerhalb der Julia LOAD_PATH gespeichert sind. In diesem Fall können Sie weitere Verzeichnisse an die Umgebungsvariable LOAD_PATH anhängen. Julia wird diese Verzeichnisse dann automatisch durchsuchen, wenn Sie den Befehl import oder using eingeben.

Eine Möglichkeit, dies zu tun, ist Folgendes zu Ihrem .basrc, .profile, .zshrc hinzuzufügen.

export JULIA_LOAD_PATH="/path/to/module/storage/folder" 

Damit wird dieses Verzeichnis an die Standardverzeichnisse angehängt, nach denen Julia suchen wird. Wenn Sie dann

julia> LOAD_PATH 

laufen sollte es zurückgeben

3-element Array{ByteString,1}: 
"/path/to/module/storage/folder" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/local/share/julia/site/v0.4" 
"/Applications/Julia-0.4.5.app/Contents/Resources/julia/share/julia/site/v0.4" 

können Sie jetzt frei using Hello laufen und Julia wird das Modul automatisch (sofern finden, da es unter /path/to/module/storage/folder gespeichert.

Weitere Informationen, werfen Sie einen Blick auf this Seite von der Julia Docs.

2

Obwohl 张 实 s die Antwort ist die meisten Conv enient, sollten Sie nicht include außerhalb der REPL verwenden. Wenn Sie eine Programmdatei schreiben, müssen Sie das Problem beheben, indem Sie das entsprechende Verzeichnis zu LOAD_PATH hinzufügen. Remy gibt eine sehr gute Erklärung dafür, aber es lohnt sich auch zu erklären, warum man das überhaupt machen sollte. (Zusätzlich aus der Dokumentation: push!(LOAD_PATH, "/Path/To/My/Module/") aber beachten Sie Ihr Modul und die Dateien haben den gleichen Namen haben)

Das Problem ist, dass alles, was Sie include wird richtig definiert werden, in dem Sie includenennen, auch wenn es auch an anderer Stelle definiert ist. Da das Ziel von Modulen wiederverwendet wird, werden Sie wahrscheinlich MyModule in mehr als einer Datei verwenden. Wenn Sie in jeder Datei include aufrufen, hat jede ihre eigene Definition von MyModule, und obwohl sie identisch sind, sind dies unterschiedliche Definitionen. Das bedeutet, dass alle in der MyModule definierten Daten (z. B. Datentypen) nicht identisch sind.

Um zu sehen, warum dies ein großes Problem ist, sollten Sie diese drei Dateien:

types.jl

module TypeModule 
struct A end 
export A 
end 

a_function.jl

include("types.jl") 
module AFunctionModule 
using TypeModule 
function takes_a(a::A) 
    println("Took A!") 
end 
export takes_a 
end 

function_caller.jl

include("a_function.jl") 
include("types.jl") 
using TypeModule, AFunctionModule 
my_a = A() 
takes_a(my_a) 

Wenn Sie laufen julia function_caller.jl erhalten Sie MethodError: no method matching takes_a(::TypeModule.A). Dies liegt daran, dass der Typ A, der in function_caller.jl verwendet wird, sich von dem in a_function.jl verwendeten unterscheidet. In diesem einfachen Fall können Sie das Problem tatsächlich beheben, indem Sie die Reihenfolge der Includes in function_caller.jl umkehren (oder einfach include("types.jl") vollständig aus function_caller.jl löschen! Das ist nicht gut!). Was aber, wenn Sie eine andere Datei b_function.jl wollten, die auch einen in TypeModule definierten Typ verwendet? Sie müssten etwas sehr Hacky machen. Oder Sie könnten einfach Ihren LOAD_PATH ändern, damit das Modul nur einmal definiert wird.