2013-11-13 2 views
3

В Nim я могу написать следующий код для импорта внешнего модуля:Как восстановить поврежденный импорт в 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") 

В самом деле, а не просто сообщение об ошибке, я хотел бы сделать некоторые модули по желанию, так что компиляция все еще продолжается вперед, возможно, с уменьшенной функциональностью. Это возможно?

РЕШЕНИЕ EDIT: На основании ответа здесь моя версия, как решить эту проблему, сначала вам нужно 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

Для авторов Nimrod был запрошен лучший механизм, см. Https://github.com/Araq/Nimrod/issues/671. –

ответ

2

Насколько я знаю, нет (простого) способа сделать это. Что вы можете сделать, так это использовать отдельный этап настройки/проверки в своей сборке. Например:

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 в configure.nim также).

Смежные вопросы