2017-04-19 139 views
5

基本上我想要一個可以使用超出範圍的功能的模塊。 我需要這個,因爲我的工作將只提供一個框架,用戶將能夠把自己的代碼他,像這樣這樣如何使用模塊內部模塊外部的功能

Simulation.jl

abstract AbstractType 

function startSimulation(unknown::AbstractType) 
    doStuff(unknown) 
end 

MyModule.jl

module MyModule 
    include("Simulation.jl") 
    export AbstractType, startSimulation 
end 

SomeImplementation.jl

type ConcreteType <: AbstractType 
    variable::Int64 
end 

doStuff(me::ConcreteType) 
    me.variable 
end 

終於Main.j升

# push!(LOAD_PATH, pwd()) # for local usage 
using MyModule 
include("SomeImplementation.jl") 
startSimulation(ConcreteType(5)) 

凡Simulation.jl和MyModule.jl都是由我和SomeImplementation.jl和Main.jl寫入由用戶編寫。

現在上面的例子不起作用,因爲模塊有它們自己的命名空間,甚至SomeImplementation.jl在第3行的main中被導入,解釋器將不會在Simulation.jl的第4行看到它。

我無法在MyModule.jl中導入任何東西,因爲我無法知道用戶如何命名他的東西或他甚至可能需要什麼額外的庫。

有沒有辦法做到這一點與模塊?否則,我只是不使用模塊。

回答

10

這裏的答案是在MyModule內爲所有要調用的函數創建存根,作爲AbstractType的自定義子類型的必需界面。也就是說,內MyModule,你必須:

abstract AbstractType 

doStuff(::AbstractType) = error("custom AbstractType objects must define a `doStuff` method) 

function startSimulation(unknown::AbstractType) 
    doStuff(unknown) 
end 

然後具體實現只需要專門通過導入,或限定它的doStuff方法添加到函數在MyModule中:

MyModule.doStuff(me::ConcreteType) 
    me.variable 
end 
+0

謝謝很多!尤其是存根將幫助很多人通知用戶如何對我的界面進行編碼。我沒有移動我的startSimulation函數tho。你爲什麼把它放到模塊文件中的任何原因? – Nozdrum

+0

如何將模塊組織爲單獨的文件並不重要。這段代碼只需要直接或者通過'include'就可以在'module'塊中生存。 –