Luaリファレンス 要注意点 ~コンパイル/Eval~†
dofile("somefile.lua")†
要するにimport, includeの類。
ただしpythonでいうところのreloadの機能を兼ねる
プログラム実行後に、somefile.luaを変更し、再びどこかで、dofile をすると、その内容が反映される。
dofile(filename)†
先述した通り。
ファイル(のチャンクを)中間コードにコンパイルして、実行する
loadfile(filename)†
該当のファイル(のチャンクを)中間コードにコンパイルして返す。
内容を実行はしない。
返り値:
成功 コンパイル済みチャンク
失敗 nil と エラーメッセージ (例: nil, cannot open *****.lua)
を返す。
loadfileはチャンクを実行しない ので注意。
即ち、dofileとloadfileの関係は自作するなら、以下のようにあらわせる
function dofile (filename)
local f = assert(loadfile(filename)) -- loadfileは実行しない。コンパイルしたチャンクを無名関数として返すのみ
return f() -- 実行
end
loadstring("i=i+1")†
loadstringは、文字列をチャンクとみなし、中間コードに無名関数としてコンパイルして、
その関数への参照を返す。
それは「可変長引数」を持つ無名関数となる。
よって
loadstring("a = 1")
↓
function (...) a = 1 end
と等価である。
このように、loadstringの返り値は、関数として評価(要するに( )を付ける)ことで、実行可能である 。
i=3
f = loadstring("i=i+1")
f()
print(i)
ということが可能。以下のようにloadstringによって返ってきた値をそのまま()で評価して
loadstring("print('OK')")()
とすることも出来る。
チャンクと名前空間†
loadstringを利用する際は、対象記述対象は、グローバル変数だということ。
i = 32
local i = 0
f = loadstring("i=i+1;print(i)")
g = function() i=i+1;print(i) end
print(f()) -- 33 loadstringで操作していたのは、あくまでグローバル
print(g()) -- 1 こちらはローカル。
読み込み文字列をeval†
local l = io.read()
local f = assert(loadstring("return " .. l ))
print("the expression is " .. f() )
簡単なREPL(入力コンソール)の例†
入力値として「x*2」などとして確認してください。
print "enter function to be plotted (with variable 'x'):"
local l = io.read()
local f = assert(loadstring("local x = ...; return " .. l))
for i=1, 20 do
print(string.rep("*", f(i)))
end