困った時の自分用メモ

読んだ本を考察してメモったり、自分でいじった物の感想をメモったりする場。週1更新を目指します。

Luaの話~dofileとloadとloadfileの使い分けを考えてみた~

結論から言うと、どれも大差ないと思う。というより、筆者にも判断が付かなかった。
以下、検証内容。

〇dofile
もふねこで使ったのはこれ。ファイルを指定すると、それを使えるようにする。

〇load
オンメモリ上の文字列を渡すと、それをコンパイル?してプログラムとして解釈してくれる。
戻り値を実行して、初めて有効化される。
以下、検証コード。

function LoadTest()
    -- indexを local indexとすると
    -- stack:1 LUA_TSTRING : [string "index = index + 1"]:1: attempt to perform arithmetic on global 'index' (a nil value)
    -- と、エラーになる
    -- loadのコンパイルはグローバル環境で行われるらしいから、グローバルアクセスできる変数じゃないとダメってことかな
    -- http://qiita.com/zenwerk/items/699a8b73245fcf61c426
    local loadChunk = load("index = index + 1")
    index = 0
    LuaUnityDebugLog("i = "..index)-- 0
    loadChunk()
    LuaUnityDebugLog("i = "..index)-- 1

    -- 試しに、関数定義とかしてみる
    -- loadChunk2(10)とかやると、エラーになる
    -- loadした物を、関数呼び出し形式で呼び出す事によって、初めて有効化される?
    -- 使い道としては、DoFileと比べると、わざわざファイル化しなくてもいいという点があげられるので、
    -- サーバーからの文字列や、ユーザー入力による物を検証して、文字で渡せば、その処理が有効化されるって感じやね
    -- load("function test(num) return num*2 end function test2(num) return num/2 end")()
    -- この書き方も可能
    local loadChunk2 = load("function test(num) return num*2 end function test2(num) return num/2 end")
    -- この時点だと、testが無いとエラーになる
    --ret1 = test(10)
    --LuaUnityDebugLog("ret1 = "..ret1)
    loadChunk2()
    
    ret2 = test(10)
    ret3 = test2(10)
    LuaUnityDebugLog("ret2 = "..ret2)-- 20
    LuaUnityDebugLog("ret3 = "..ret3)-- 5
end

〇loadfile
ファイルを指定すると、それを使えるようにする。
戻り値を実行して、初めて有効化される。
以下、検証コード。

LuaFileTest.lua
index = index + 1
function SaveLocalLuaScriptCallback()
    LuaUnityDebugLog("PERSISTENE:"..PersistentDataPath)-- PERSISTENE:/storage/emulated/0/Android/data/com.mochimoffu.mofuneko/files
    local loadChunk = loadfile(PersistentDataPath.."/LoadFileTest.lua")
    if loadChunk == nil then
        LuaUnityDebugLog("loadChunk is nil")
    else
        index = 0
        LuaUnityDebugLog("i = "..index)-- 0
        loadChunk()
        LuaUnityDebugLog("i = "..index)-- 1
    end
end

〇結論というか推論というか
loadは、まぁ文字列を直接渡すという点では他の2つとは使い道を分けられそう。
dofileとloadfileの差だが、loadfileの戻り値の実行まで勝手にやってくれるのが、dofileなのではないかなと思った

〇余談
Android実機の場合は、StreamingAssets内の物は直接指定できないので、StreamingAssetsからPersistentDataPathにファイルをコピーしてから、 そのパスを指定する事