webmcp
diff framework/bin/mcp.lua @ 324:1c3ba14bd679
Root __init.lua function must not set global variables without _G now; Documentation for "_" function added
author | jbe |
---|---|
date | Mon Mar 23 22:41:40 2015 +0100 (2015-03-23) |
parents | 4603e8781fb9 |
children | ae6e889fe264 |
line diff
1.1 --- a/framework/bin/mcp.lua Mon Mar 23 22:17:33 2015 +0100 1.2 +++ b/framework/bin/mcp.lua Mon Mar 23 22:41:40 2015 +0100 1.3 @@ -13,36 +13,28 @@ 1.4 1.5 A reference to the global namespace. To avoid accidental programming errors, global variables cannot be set directly, but they must be set through the _G reference, e.g. use _G.foo = true to set the variable "foo" to a value of true. 1.6 1.7 -The only exception is the <framework>/env/__init.lua file and the <application>/env/__init.lua file, in which global variables may be set without using the _G reference. 1.8 - 1.9 Note that the global namespace may or may not be shared between requests (Moonbridge creates multiple forks of the Lua machine). To set variables that are to be cleared after the request has been finished, an application may use the "app" table, e.g. app.foo = true to set the variable app.foo to a value of true, which will be cleared automatically when the request has ended. 1.10 1.11 --]]-- 1.12 local _G = _G 1.13 local allowed_globals = {} 1.14 -local global_metatable = { 1.15 - __index = _G, 1.16 - __newindex = function(self, key, value) 1.17 - _G[key] = value 1.18 - end 1.19 -} 1.20 -_ENV = setmetatable( 1.21 - {}, -- proxy environment used within mcp.lua and by all chunks loaded through loadcached(...) 1.22 - global_metatable 1.23 -) 1.24 -local function protect_globals() -- called before first configuration file is loaded 1.25 - function global_metatable.__newindex(self, key, value) 1.26 - if allowed_globals[key] then 1.27 - _G[key] = value 1.28 - else 1.29 - if type(key) == "string" and string.match(key, "^[A-Za-z_][A-Za-z_0-9]*$") then 1.30 - error('Attempt to set global variable "' .. key .. '" (hint: use _G.' .. key .. '=<value> to override protection mechanism)', 2) 1.31 +local protected_environment = setmetatable( 1.32 + {}, -- proxy environment used all chunks loaded through loadcached(...) 1.33 + { 1.34 + __index = _G, 1.35 + __newindex = function(self, key, value) 1.36 + if allowed_globals[key] then 1.37 + _G[key] = value 1.38 else 1.39 - error('Attempt to set global variable', 2) 1.40 + if type(key) == "string" and string.match(key, "^[A-Za-z_][A-Za-z_0-9]*$") then 1.41 + error('Attempt to set global variable "' .. key .. '" (hint: use _G.' .. key .. '=<value> to override protection mechanism)', 2) 1.42 + else 1.43 + error('Attempt to set global variable', 2) 1.44 + end 1.45 end 1.46 end 1.47 - end 1.48 -end 1.49 + } 1.50 +) 1.51 --//-- 1.52 1.53 --[[-- 1.54 @@ -65,7 +57,7 @@ 1.55 if file then 1.56 local filedata = assert(file:read("*a")) 1.57 assert(file:close()) 1.58 - local func, compile_error = load(filedata, "=" .. filename, nil, _ENV) 1.59 + local func, compile_error = load(filedata, "=" .. filename, nil, protected_environment) 1.60 if func then 1.61 cache[filename] = func 1.62 return func 1.63 @@ -194,7 +186,6 @@ 1.64 -- autoloader system for WebMCP environment "$WEBMCP_FRAMEWORK_PATH/env/", 1.65 -- application environment extensions "$WEBMCP_BASE_PATH/env/" 1.66 -- and models "$WEBMCP_BASE_PATH/model/" 1.67 -local root_init -- function which executes the __init.lua file in the environment's root 1.68 do 1.69 local weakkey_mt = { __mode = "k" } 1.70 local autoloader_category = setmetatable({}, weakkey_mt) 1.71 @@ -279,15 +270,13 @@ 1.72 return rawget(self, key) 1.73 end 1.74 install_autoloader(_G, nil, "") 1.75 - function root_init() -- upvalue 1.76 - try_exec(WEBMCP_FRAMEWORK_PATH .. "env/__init.lua") 1.77 - try_exec(WEBMCP_BASE_PATH .. "env/__init.lua") 1.78 - end 1.79 + try_exec(WEBMCP_FRAMEWORK_PATH .. "env/__init.lua") 1.80 + try_exec(WEBMCP_BASE_PATH .. "env/__init.lua") 1.81 end 1.82 1.83 -- define post-fork initialization function (including loading of "multirand" library) 1.84 local function postfork_init() 1.85 - _G.multirand = require "multirand" 1.86 + multirand = require "multirand" 1.87 execute.postfork_initializers() 1.88 end 1.89 1.90 @@ -334,19 +323,13 @@ 1.91 end 1.92 end 1.93 1.94 --- execute the __init.lua file in the environment's root 1.95 -root_init() 1.96 - 1.97 --- prohibit (unintended) definition of new global variables 1.98 -protect_globals() 1.99 - 1.100 -- execute configurations and pre-fork initializers 1.101 for i, config_name in ipairs(WEBMCP_CONFIG_NAMES) do 1.102 execute.config(config_name) 1.103 end 1.104 execute.prefork_initializers() 1.105 1.106 --- perform post-fork initializations in case of interactive mode 1.107 +-- perform post-fork initializations (once) in case of interactive mode 1.108 if WEBMCP_MODE == "interactive" then 1.109 postfork_init() 1.110 end