dofileとrequireはよく似た関数ですが、いくつか違いがあります。まずrequireは通常拡張子".lua"無しでモジュールを指定します。これを実装してみます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function require(m) | |
dofile(m..".lua") | |
end |
前回、dofileのファイルシステムを置き換えているので置き換え版のdofileを流用することでLuaだけで書けました。厳密にはpackage.pathを考慮していないという問題がありますが、これだけで用足りることも多いと思います。
ところで、requireで比較的重要なdofileとの違いが、重複requireガードです。これはpackage.loadedテーブルにロード結果が記録される事で行われます。実際にテーブルの中身をprintで出力してみると、以下のようになりました。(左がキー、右が値)
debug table: 00C9D770キーを見ると、luaL_openlibsでロードされるLuaの標準ライブラリに混じってrequireでロードしたモジュール(ここではvec4, bind_win, my_classがそれです)の名前が見えます。対して値はそのモジュールをロードした時のreturn値が格納されています。(return値が無い場合はtrue)
vec4 true
coroutine table: 00C98AA8
_G table: 00C92760
package table: 00C98828
math table: 00C9A2D0
my_class userdata: 00C9C3B8
io table: 00C98C38
os table: 00C99880
bind_win true
string table: 00C99FB0
utf8 table: 00C9D6D0
table table: 00C98BE8
また、この値は同じモジュールの二回目以降のrequireで返される値としても使われます。以下の例は、dofileが毎回math.random()を実行するのに対して、requireは初回呼び出し時の値をpackage.loadedにキャッシュする事を確かめるものです。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
print("calling with dofile", dofile("random.lua"), dofile("random.lua"), dofile("random.lua")) | |
print("calling with require", require("random"), require("random"), require("random")) | |
assert(require("random") == package.loaded["random"]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
return math.random() |
以上を踏まえたファイルシステム置き換え版のrequireは以下のようになります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function require(m) | |
package.loaded[m] = package.loaded[m] or dofile(m..".lua") or true | |
return package.loaded[m] | |
end |
No comments:
Post a Comment