2018 Update:この質問に対する答えは長年にわたって複数回変更されているため、必ずすべての回答を確認してください。この更新の時点で、おそらく_Revise.jl
_回答が最良の解決策です。
ファイル「/SomeAbsolutePath/ctbTestModule.jl」があり、その内容は次のとおりです。
_module ctbTestModule
export f1
f1(x) = x + 1
end
_
「〜/ .juliarc.jl」を実行するターミナルでJuliaを起動します。スタートアップコードには次の行が含まれます。
_Push!(LOAD_PATH, "/SomeAbsolutePath/")
_
したがって、すぐにJuliaコンソールに入力できます。
_using ctbTestModule
_
モジュールをロードします。予想どおりf1(1)
は_2
_を返します。今、私は突然_f1
_を編集したいと決めました。エディターで「/SomeAbsolutePath/ctbTestModule.jl」を開き、内容を次のように変更します。
_module ctbTestModule
export f1
f1(x) = x + 2
end
_
現在、アクティブなジュリアセッションでモジュールをリロードしようとしています。やってみる
_using ctbTestModule
_
しかし、f1(1)
はまだ_2
_を返します。次に試す
_reload("ctbTestModule")
_
here が提案されているように、f1(1)
はまだ_2
_を返します。最後に、私は試します:
_include("/SomeAbsolutePath/ctbTestModule.jl")
_
こちら 、これはnot理想的です。現在のディレクトリが「/ SomeAbsolutePath」ではない可能性があるため、絶対パスを完全に入力する必要があるためです。警告メッセージ_Warning: replacing module ctbTestModule
_が表示されますが、これは有望に聞こえますが、f1(1)
はまだ_2
_を返します。
現在のジュリアセッションを閉じ、新しいセッションを開始し、_using ctbTestModule
_と入力すると、目的の動作が得られます。つまり、f1(1)
は_3
_を返します。しかし、明らかに、Juliaを再起動せずにこれをやりたいです。
だから、私は何を間違っていますか?
その他の詳細:Ubuntu 14.04上のJulia v0.2。
この問題の基礎は、モジュールのリロードの合流ですが、モジュール内の事柄を再定義できないことですMain( こちらのドキュメントを参照 )-つまり 少なくとも新しい関数workspace()が利用可能になるまで 2014年7月13日。 0.3プレリリースにはそれが必要です。
次の単純なモジュールを検討してください
module TstMod
export f
function f()
return 1
end
end
次にそれを使用します。
Julia> using TstMod
Julia> f()
1
関数f()がreturn 2に変更された場合モジュールがリロードされ、fが実際に更新されますが、モジュールでは再定義されませんMain。
Julia> reload("TstMod")
Warning: replacing module TstMod
Julia> TstMod.f()
2
Julia> f()
1
次の警告は問題を明確にします
Julia> using TstMod
Warning: using TstMod.f in module Main conflicts with an existing identifier.
Julia> using TstMod.f
Warning: ignoring conflicting import of TstMod.f into Main
ただし、新しい関数workspace()はMainリロードの準備TstMod
Julia> workspace()
Julia> reload("TstMod")
Julia> using TstMod
Julia> f()
2
また、前のMainはLastMain
Julia> whos()
Base Module
Core Module
LastMain Module
Main Module
TstMod Module
ans Nothing
Julia> LastMain.f()
1
パッケージRevise
を使用します。
Pkg.add("Revise") # do this only once
include("src/my_module.jl")
using Revise
import my_module
新しいREPLセッションでこれを開始する必要がある場合があります。 import
の代わりにusing
を使用していることに注意してください。これは、using
がMain
モジュールの関数を再定義しないためです(@Maciek Leksと@waTeimで説明)。
他の解決策:workspace()
と比較したRevise.jl
の2つの利点は、(1)はるかに高速であり、(2 ) このGitHubの問題 で説明されているように、workspace()
は0.7で非推奨になったため、将来も保証されます。
Julia> VERSION
v"0.7.0-DEV.3089"
Julia> workspace()
ERROR: UndefVarError: workspace not defined
そして、GitHubの貢献者が推奨するRevise.jl
:
「ワークスペースは非推奨です。代わりにRevise.jlをチェックしてください」などのメッセージを追加する必要がありますか?
Julia 0.6.3でも、モジュールがimport
などの他のモジュールを呼び出すと、workspace()
、reload
、およびDataFrames
の3つの以前のソリューションは失敗します。 3つの方法すべてで、同じREPLでそのモジュールを2回呼び出したときに同じエラーが発生しました。
ERROR: LoadError: MethodError: all(::DataFrames.##58#59, ::Array{Any,1}) is ambiguous. Candidates: ...
また、次のような多くの警告メッセージが表示されました。
WARNING: Method definition macroexpand(Module, ANY) in module Compat at /Users/mmorin/.Julia/v0.6/Compat/src/Compat.jl:87 overwritten in module Compat at /Users/mmorin/.Julia/v0.6/Compat/src/Compat.jl:87.
Juliaセッションの再起動は機能しましたが、面倒でした。 再エクスポートパッケージのこの問題 を見つけましたが、同様のエラーメッセージが表示されます。
MethodError: all(::Reexport.##2#6, ::Array{Any,1}) is ambiguous.
そして、1人の貢献者の提案に従いました:
これは、workspace()を使用せずに発生しますか?この関数は、パッケージとの相互作用が不十分なことで有名です。これが、0.7で非推奨になった理由の1つです。
私の謙虚な意見では、より良い方法は、報告された問題にimport
の代わりにusing
を最初から使用することです。
モジュールを検討してください:
_module ModuleX1
export produce_text
produce_text() = begin
println("v1.0")
end
println("v1.0 loaded")
end
_
次に、REPLで:
_Julia> import ModuleX1
v1.0 loaded
Julia> ModuleX1.produce_text()
v1.0
_
モジュールのコードを更新して保存します。
_module ModuleX1
export produce_text
produce_text() = begin
println("v2.0")
end
println("v2.0 loaded")
end
_
次に、REPLで:
_Julia> reload("ModuleX1")
Warning: replacing module ModuleX1
v2.0 loaded
Julia> ModuleX1.produce_text()
v2.0
_
import
よりもusing
を使用する利点:
workspace()
を呼び出す必要はありませんimport
よりもusing
を使用する場合の欠点:
編集済み:以下の会話に従って、「短所...」から「エクスポートされていない名前にさえも、モジュールへのフルアクセス」を破棄しました。
ジュリアではv0.6.を使用しているようですworkspace()はno必要です:単純にreload(MyModule)アクティブなREPLセッションで、期待どおりに動作します(MyModuleを含むソースファイルに加えられた変更は、アクティブなREPLセッション)に反映されます。
これは、importまたはsingのいずれかによってスコープに取り込まれたモジュールに適用されます
新しいモジュールをゼロから作成したかったため、1.0でさまざまな答えを試しても満足のいく結果が得られませんでしたが、次のことがうまくいきました。
実行するプロジェクトに使用するディレクトリ内のJulia REPL
pkg> generate MyModule
これにより、次の構造のようなサブディレクトリが作成されます。
MyModule
├── Project.toml
└── src
└── MyModule.jl
モジュールコードをMyModule.jl
に配置します。ディレクトリMyModule
に変更し(またはIDEで開きます)、次のコードでファイルScratch.jl
を追加します。
Pkg.activate(“.”)
using Revise
import MyModule
次に、以下のテストにコードを追加して、REPLをリロードせずにすべてを更新できます。