2016-08-30 10 views
3

私はモジュールを持っていると仮定しましょう:LUA環境とモジュール

-- env.lua 

local env = {} 

function env.resolve(str) 
    print("mod", _ENV) 

    if _resolve_path ~= nil then 
    return _resolve_path(str) 
    else 
    error("bad env") 
    end 
end 

return env 

し、それを使用していくつかのコード:私が達成したいのですがどのような

-- sandbox demo 
-- run as: lua env-test.lua 

env = require('env') 

function _resolve_path(path) 
    return "/" .. path 
end 

print("before main()") 
print("", _ENV) 
print("", env.resolve("test")) 

local sandbox 
do 
    local _ENV = { 
    print = print, 
    env = env, 
    _resolve_path = function (path) 
     return "/chroot/" .. path 
    end 
    } 
    function sandbox() 
    print("from sandbox()") 
    print("", _ENV) 
    print("", env.resolve("test")) 
    end 
end 

sandbox() 

print("after main()") 
print("", _ENV) 
print("", env.resolve("test")) 

はサンドボックスからenv.resolve()は()を使うだろうということです環境からのカスタム_resolve_path関数しかし、環境はサンドボックス関数から呼び出されたコードには適用されません。目標は、どこから呼び出されたかに応じていくつかのモジュールがどのように動作するかを補うことです。例えば。異なるローカル_resolve_path()関数を持つサンドボックス{1,2,3}()を持っています。

答えて

2

モジュールをrequireでロードすると、モジュールはグローバル環境にバインドされます。関数が環境内で作成されると、その関数はその存続期間全体にわたってその環境を持っています。

Lua 5.2以前は、を使用して環境を変更できましたが、環境は現在レキシカルです。環境は、_ENVの値を変更することによってのみ、デバッグライブラリで変更することができます。

異なる環境でどのように同じ機能を実行できますか?

function env.resolve(str, _ENV) 
    print("mod", _ENV) 
    if _resolve_path ~= nil then 
    return _resolve_path(str) 
    else 
    error("bad env") 
    end 
end 

あなたは、その後のようなresolve呼び出す:あなたは環境がすべてのresolveコールに指定する必要はありませんでした好むならば、

env.resolve('test', _ENV) 

をしたり、パラメータとして環境に渡すことができますあなたはそれぞれの新しい環境にresolve機能をバインドすることができます。

-- env.lua 
local print = print 
local error = error 
local env = {} 

-- this is the actual resolve function that takes the environment as a parameter 
local function resolve_env(str, _ENV) 
    print("mod", _ENV) 
    if _resolve_path ~= nil then 
    return _resolve_path(str) 
    else 
    error("bad env") 
    end 
end 

-- this is the module (ie. global) resolve 
function env.resolve(str) 
    return resolve_env(str, _ENV) 
end 

-- this function binds a resolve function to a sandbox environment 
function env.bind(_ENV) 
    _ENV.env = { 
    resolve = function(str) 
     return resolve_env(str, _ENV) 
    end 
    } 
    return _ENV 
end 

return env 

サンドボックスが可能になりましセットアップ拘束決意:

結果が得られます
-- sandbox.lua 
env = require 'env' 

function _resolve_path(path) 
    return "/" .. path 
end 

print("before main()") 
print("", _ENV) 
print("", env.resolve("test")) 

local sandbox; do 
    local _ENV = env.bind{ 
    print = print, 
    _resolve_path = function (path) 
     return "/chroot/" .. path 
    end 
    } 

    function sandbox() 
    print("from sandbox()") 
    print("", _ENV) 
    print("", env.resolve("test")) 
    end 
end 

sandbox() 

print("after main()") 
print("", _ENV) 
print("", env.resolve("test")) 

$ lua sandbox.lua 
before main() 
     table: 00612f40 
mod  table: 00612f40 
     /test 
from sandbox() 
     table: 0061c7a8 
mod  table: 0061c7a8 
     /chroot/test 
after main() 
     table: 00612f40 
mod  table: 00612f40 
     /test 
+0

もenv.resolve()を呼び出して、他の方法でこの作品を作るためにそこのソリューションです。今すぐリバウンドenv.resolve()関数が表示されないenv.load()、env.write()があるとしましょう:/ – ensonic

関連する問題