3

Nimでは、次のコードを記述して外部モジュールをインポートできます。

import myFancyPantsModule
...
# And here I'd use the fancyPants proc

これは、モジュールがある限り問題なく機能しますが、コードをダウンロードする可能性があり、モジュールがインストールされていない場合、コンパイルはあまりユーザーフレンドリーではないメッセージで失敗します。

$ nim c fancyProgram.nim
fancyProgram.nim(1, 7) Error: cannot open 'myFancyPantsModule'

例外と同様にキャッチして、ステートメントと同様のコードの代替ブランチを実行importできるようにラップする方法はありますか? のようなマクロまたは次のように使用できるものを見つけたいと思っていました。whenimportable

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現在のバージョンにはコンパイル時にファイルを生成するプロセスがないため、外部コンパイルだけでなく、チェック用の一時ファイルを生成する別のプロセスも生成する必要があるのは非常に残念です。

4

1 に答える 1

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 実行可能ファイルがパスにあると仮定しています (そうでない場合は、nimrod パスconfigure.nimも指定する必要があります)。

于 2013-11-13T17:58:40.960 に答える