Nimのモジュール
Nimは普段のプログラミングに使える汎用のプログラミング言語ですが、
言語としてはシステムプログラミングを意識している言語です。
システムプログラミング言語としてはC/C++がメジャーな言語ですが、NimではC/C++と違って優秀なモジュールシステムを使うことができます。
今回はそんなモジュールの話です。
基本
基本的にはpython風の文法になっています。
import
Nimのモジュールシステムで他のモジュールを使うようにするには、
import モジュール名
と書くことによって使えます。
例えば、標準ライブラリでよく使うstrutilsをimportするには
import strutils
とすればすぐに使うことができます。
except
importする際に一部の関数などをインポートしないようにするexceptがあります。
import strutils except `%`, toUpper echo "$1" % "abc".toUpper # compile error!
from
他にも、特定の関数のみをインポートするfrom文があります。
from strutils import `%` echo "$1" % "abc" echo strutils.replace("abc", "a", "z") # モジュール名を含む場合使用可能
importはカンマで区切ることによって1行で複数モジュールをインポートすることができます。
import strutils, sequtils
さらに、asで別名にすることができます。
import strutils as su
インポートした関数などは、そのまま関数名で呼び出すことができ、strutils.format
のように呼び出すこともできます。
別のモジュール同士に同じ関数名が含まれている場合は、モジュール名をつけることによって区別することができます。
# modulea.nim proc echoInt*(a: int) = echo a
# moduleb.nim proc echoInt*(a: int) = echo a
import modulea import moduleb echoInt(1) # compile error! modulea.echoInt(1) # works! moduleb.echoInt(1) # works!
Nimのモジュールシステムではimport モジュール名
とした際に、
- 標準ライブラリ
- パッケージマネージャのnimbleによってインストールされたライブラリ
- 同ディレクトリ
からインポートしようとします。
インポートする際にはモジュール名に相対パスを使うことができ、相対パスの/
を.
に置き換えることもできます。
# modules/foo.nim proc echoInt*(a: int) = echo a
import modules.foo echoInt(1)
Asterisk(public)
サンプルの関数に付いているアスタリスク*
は関数を公開(public)するようにする文法です。
関数以外にもマクロや型などにも付けることができます。
export
他モジュールの関数などを別モジュールから公開するexportがあります。
# objmodule.nim type MyObject* = object
# basemodule.nim import objmodule export objmodule.MyObject proc `$`*(x: MyObject): string = "my object"
# main.nim import basemodule var x: MyObject echo $x
include
includeは他のファイルをそのまま取り込む文です。Cのプリプロセッサでいう#include <***.h>
ですね。
include fileA, fileB, fileC
使いどころとしては複数のAPIのwrapperを作るとき、コンパイル時に使用するAPIを切り替えできるようにする際にwhenと組み合わせて使ったりします。
const audioAPI = "wasapi" when audioAPI == "WASAPI": include wasapi.nim elif audioAPI == "OpenAL": include openal.nim elif audioAPI == "CoreAudio": include coreaudio.nim else: raise newException(Exception, "Unknown Audio API")
nimble
nimbleはNimのパッケージマネージャ兼ビルドシステムです。
C/C++と違い、公式で用意されているものなのでほとんどのNimライブラリがコマンド一発で入るというとても便利なものになっています。
$ nimble install csv
上記のコマンドでcsvパーサが一発で入ります。
後は、
import csv
を書いて直ぐに使い始めることができます。
nimbleで入れられるライブラリとして特徴的なのはcompilerライブラリです。
compilerライブラリは文字通りコンパイラのライブラリで、これはNimのコンパイラのライブラリになっています。
NimはコンパイラがNim自身で書かれているので(セルフホスティング)、こうしてコンパイラ自身をライブラリとして使えるようになっています。
まとめ
Nimのモジュールシステムは非常に優れており、これだけでC/C++に比べてアドバンテージがあるのではないでしょうか。
特にcompilerライブラリは他の言語ではなかなか無いライブラリで、とても興味深いのでいずれ単体で記事にしたいところです。
おまけ
NimではC/C++のようにコンパイル時にコンパイラに必要なファイル全てを渡す必要はなく、一つのファイルを渡せば後はimportから自動的に解析してコンパイルしてくれます。
さらにNimではインクリメンタルコンパイルができ、一度コンパイルしてしまえばあとは更新があった部分のみを再コンパイルしてくれるので2回目以降のコンパイルは非常に高速です。
1回目のコンパイルは標準ライブラリを含めてコンパイルされるので時間がかかりますが、2回目以降は高速化されるので実用上問題になることは少ないでしょう。
Nimではロードマップでインクリメンタルコンパイルの大幅な改善も予定されているのでさらに高速になることが予想されるので期待ですね!