requireのパスあれこれ

Aviutl拡張編集スクリプトで外部LuaファイルやCのdllをrequireして使うと、
時に高速化を図れたり、複数のスクリプトで関数や処理系の使い回しができる。

module("addmodule", package.seeall)
add = function(v1,v2)
    return v1+v2
end
local addm = require "addmodule"
local a = addm.add(1,2)
debug_print(a)  --3 が出力される

●パスの確認

requireに指定するのはモジュール名だけで、
ファイルがどこのディレクトリにあるかなどは指定できない。
ではLuaはどこを探すのか。
それはグローバル変数 package.path, package.cpathで定義されている。
package.path がluaのモジュールを、package.cpath がCのモジュールを探すパスである。

requireした時のLuaの挙動は、
まず既にロードされていればその値を返す。
ロードされていなければpackage.pathに示されたパスからluaのローダを探し、
見つからなければpackage.cpathからCのローダを探すという順序らしい。
より詳しくはLua5.1リファレンスマニュアル

テキストオブジェクトに下の内容を貼り付けると、デフォルトのパスを確認できる。
どうやらexedit.aufのあるフォルダと、スクリプトのあるフォルダを探すようだ。

<?mes(“package.path : “..package.path)?>
<?mes(“package.cpath : “..package.cpath)?>

表示結果の「?」はロード時にモジュール名に置換される。
つまり、package.pathが「…\script\?.lua」ならば
「require “hoge”」は「…\script\hoge.lua」というファイルを探す。

●パスの変更

AviutlのLuaがモジュールを特定のフォルダしか探してくれないからといって、
.luaや.dllをスクリプトと同じフォルダにいくつも作ると、フォルダの中が煩雑になる。
できれば共通外部モジュールは別途「lib」などというフォルダを作ってその中に入れたい。

あるいは、ファイル名はモジュール名に必ず接頭辞「lib_」をつけるというルールで管理したい。

そんな時はpackage.pathを変更する。

--スクリプトと同じ階層の「lib」フォルダの中に、luaファイルを入れる場合
package.path = obj.getinfo("script_path").."lib\\?.lua"

--「lib_」接頭辞をつける場合
package.path = obj.getinfo("script_path").."lib_?.lua"

--拡張子が.outのファイルから読み込む場合
package.path = obj.getinfo("script_path").."?.out"

--デフォルトパスを残しつつ、libフォルダの中も読み込む場合
package.path = obj.getinfo("script_path").."lib\\?.lua;"..package.path

このパスはスクリプト呼び出し毎にリセットされるようで、毎回指定する必要がある。
逆に言うと、変更しても別のスクリプトのパス設定には影響しないので安心。

●モジュール名にドットを使う

モジュール名のドットは、読み込み時にディレクトリ区切り文字に置換される。

require "lib.mymodule"
--(package.path)\lib\mymodule.lua が読み込まれる。
--使う時は「lib.mymodule」ではなく「mymodule」
mymodule.func()

ただし、通常はrequireでモジュールの実体(テーブル)が直接返されるのに対し、
ドットを使うと読み込みに成功したかどうかの結果がbooleanで返されるようになる。
ローカル化してから使う際には注意。

local localmod = require "mymodule"
localmod.func() --成功

local localmod = require "lib.mymodule"
localmod.func() --エラー

--ローカル化は一呼吸置く。
require "lib.mymodule"
local localmod = mymodule
localmod.func()

コメントを残す

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">