在Nim中,我可以编写以下代码来导入外部模块:
import myFancyPantsModule
...
# And here I'd use the fancyPants proc
只要我有模块,这样就可以正常工作,但是对于那些可能下载代码并且没有安装模块的人来说,编译将会失败,并且会有一个非常用户友好的消息:
$ nim c fancyProgram.nim
fancyProgram.nim(1, 7) Error: cannot open 'myFancyPantsModule'
我有什么方法可以绕过import
以便我可以捕获它类似于异常并执行类似于when
语句的替代代码分支?我希望找到一些importable
- 像宏一样或者我可以使用的东西:
when importable(myFancyPantsModule):
# And here I'd use the fancyPants proc
else:
quit("Oh, sorry, go to https://github.com/nim-lang/nimble and install " &
" the myFancyPantsModule using the nimble package manager")
实际上,我想使一些模块成为可选的,而不是一个简单的错误消息,因此编译仍然可以继续进行,可能具有减少的功能。这可能吗?
解决方案编辑:根据这里的答案是我的版本如何解决问题,首先需要一个moduleChecker
二进制文件,其中包含以下来源:
import os, osproc
let tmpFile = getTempDir() / "dynamicModuleChecker.nim"
proc checkModule(module: string) =
except:
echo "Cannot write ", tmpFile, " to check the availability of modules"
quit(1)
writeFile(tmpFile, "import " & module & "\n")
finally: removeFile(tmpFile)
except:
echo("Cannot run \"nimrod check\" to check the availability of modules")
quit(1)
if execCmdEx("nim check " & tmpFile).exitCode != 0:
echo("Cannot import module " & module & ".")
quit(1)
else:
echo "OK"
if ParamCount() < 1:
quit("Pass as first parameter the module to check")
else:
checkModule(ParamStr(1))
然后,使用此命令可以使用以下宏:
import macros
macro safeImport(module, message: string): stmt =
if "OK" == gorge("./moduleChecker " & module.strVal):
result = newNimNode(nnkStmtList).add(
newNimNode(nnkImportStmt).add(
newIdentNode(module.strVal)))
else:
error("\nModule " & module.strVal &
" not available.\n" & message.strVal)
safeImport("genieos",
"Please install \"http://gradha.github.io/genieos/\"")
不幸的是,必须生成一个单独的进程,不仅是外部编译,还有另一个生成要检查的临时文件的进程,因为当前版本中没有staticWrite
来生成文件在编译时。
答案 0 :(得分:2)
据我所知,没有(简单)方法可以做到这一点。您可以做的是在构建中使用单独的配置/检查阶段。 E.g:
import macros, os, osproc
proc checkModule(module, howtomessage: string) =
except:
echo("Cannot write .conftest.nim to check the availability of modules")
quit(1)
writeFile(".conftest.nim", "import " & module & "\n")
except: nil
removeFile(".conftest.nim")
except:
echo("Cannot run \"nimrod check\" to check the availability of modules")
quit(1)
if execCmdEx("nimrod check .conftest.nim").exitCode != 0:
echo("Cannot import module " & module & ".")
echo(howtomessage)
quit(1)
checkModule "foobar", "Please install it using the Babel package manager"
然后运行类似:
nimrod cc --run configure.nim && nimrod cc main.nim
假设上面的代码存储在名为configure.nim
的文件中,并且nimrod可执行文件位于您的路径中(否则,您必须在{{1}中指定nimrod路径也)。