# HG changeset patch # User jbe # Date 1427146900 -3600 # Node ID 1c3ba14bd67974a2bf0e765f39fd784fff3aea0b # Parent 4603e8781fb9099edc8b7d043d8ebc2a18a84599 Root __init.lua function must not set global variables without _G now; Documentation for "_" function added diff -r 4603e8781fb9 -r 1c3ba14bd679 framework/bin/mcp.lua --- a/framework/bin/mcp.lua Mon Mar 23 22:17:33 2015 +0100 +++ b/framework/bin/mcp.lua Mon Mar 23 22:41:40 2015 +0100 @@ -13,36 +13,28 @@ 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. -The only exception is the /env/__init.lua file and the /env/__init.lua file, in which global variables may be set without using the _G reference. - 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. --]]-- local _G = _G local allowed_globals = {} -local global_metatable = { - __index = _G, - __newindex = function(self, key, value) - _G[key] = value - end -} -_ENV = setmetatable( - {}, -- proxy environment used within mcp.lua and by all chunks loaded through loadcached(...) - global_metatable -) -local function protect_globals() -- called before first configuration file is loaded - function global_metatable.__newindex(self, key, value) - if allowed_globals[key] then - _G[key] = value - else - if type(key) == "string" and string.match(key, "^[A-Za-z_][A-Za-z_0-9]*$") then - error('Attempt to set global variable "' .. key .. '" (hint: use _G.' .. key .. '= to override protection mechanism)', 2) +local protected_environment = setmetatable( + {}, -- proxy environment used all chunks loaded through loadcached(...) + { + __index = _G, + __newindex = function(self, key, value) + if allowed_globals[key] then + _G[key] = value else - error('Attempt to set global variable', 2) + if type(key) == "string" and string.match(key, "^[A-Za-z_][A-Za-z_0-9]*$") then + error('Attempt to set global variable "' .. key .. '" (hint: use _G.' .. key .. '= to override protection mechanism)', 2) + else + error('Attempt to set global variable', 2) + end end end - end -end + } +) --//-- --[[-- @@ -65,7 +57,7 @@ if file then local filedata = assert(file:read("*a")) assert(file:close()) - local func, compile_error = load(filedata, "=" .. filename, nil, _ENV) + local func, compile_error = load(filedata, "=" .. filename, nil, protected_environment) if func then cache[filename] = func return func @@ -194,7 +186,6 @@ -- autoloader system for WebMCP environment "$WEBMCP_FRAMEWORK_PATH/env/", -- application environment extensions "$WEBMCP_BASE_PATH/env/" -- and models "$WEBMCP_BASE_PATH/model/" -local root_init -- function which executes the __init.lua file in the environment's root do local weakkey_mt = { __mode = "k" } local autoloader_category = setmetatable({}, weakkey_mt) @@ -279,15 +270,13 @@ return rawget(self, key) end install_autoloader(_G, nil, "") - function root_init() -- upvalue - try_exec(WEBMCP_FRAMEWORK_PATH .. "env/__init.lua") - try_exec(WEBMCP_BASE_PATH .. "env/__init.lua") - end + try_exec(WEBMCP_FRAMEWORK_PATH .. "env/__init.lua") + try_exec(WEBMCP_BASE_PATH .. "env/__init.lua") end -- define post-fork initialization function (including loading of "multirand" library) local function postfork_init() - _G.multirand = require "multirand" + multirand = require "multirand" execute.postfork_initializers() end @@ -334,19 +323,13 @@ end end --- execute the __init.lua file in the environment's root -root_init() - --- prohibit (unintended) definition of new global variables -protect_globals() - -- execute configurations and pre-fork initializers for i, config_name in ipairs(WEBMCP_CONFIG_NAMES) do execute.config(config_name) end execute.prefork_initializers() --- perform post-fork initializations in case of interactive mode +-- perform post-fork initializations (once) in case of interactive mode if WEBMCP_MODE == "interactive" then postfork_init() end diff -r 4603e8781fb9 -r 1c3ba14bd679 framework/env/__init.lua --- a/framework/env/__init.lua Mon Mar 23 22:17:33 2015 +0100 +++ b/framework/env/__init.lua Mon Mar 23 22:41:40 2015 +0100 @@ -1,5 +1,19 @@ --- string localization function -function _(text, replacements) +--[[-- +translated_string = -- translated string +_( + string_to_translate, -- string to translate + { + placeholder_name1 = text1, -- replace all occurrences of "#{placeholder_name1}" with the string text1 + placeholder_name2 = text2, -- replace all occurrences of "#{placeholder_name2}" with the string text2 + ... + } +) + +Translation function for internationalization. The "_" function translates a given string to the currently selected language (see locale.set{...}). If the translated string contains placeholders in the form #{name}, then those placeholders may be automatically replaced with a corresponding substring which is taken from the table passed as optional second argument. + +--]]-- + +function _G._(text, replacements) local text = locale._get_translation_table()[text] or text if replacements then return ( @@ -15,6 +29,7 @@ return text end end +--//-- --[[-- cloned_table = -- newly generated table @@ -38,11 +53,11 @@ --//-- -- load libraries (except "multirand", which must be loaded after forking) -extos = require 'extos' -nihil = require 'nihil' -mondelefant = require 'mondelefant' -atom = require 'atom' -json = require 'json' +_G.extos = require 'extos' +_G.nihil = require 'nihil' +_G.mondelefant = require 'mondelefant' +_G.atom = require 'atom' +_G.json = require 'json' require 'mondelefant_atom_connector' -- NOTE: "multirand" library is loaded in mcp.lua after forking @@ -67,6 +82,6 @@ 'config' is a global table, which can be modified by a config file of an application to modify the behaviour of that application. --]]-- -config = {} +_G.config = {} --//--