webmcp

changeset 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 3384306aa7bc
files framework/bin/mcp.lua framework/env/__init.lua
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
     2.1 --- a/framework/env/__init.lua	Mon Mar 23 22:17:33 2015 +0100
     2.2 +++ b/framework/env/__init.lua	Mon Mar 23 22:41:40 2015 +0100
     2.3 @@ -1,5 +1,19 @@
     2.4 --- string localization function
     2.5 -function _(text, replacements)
     2.6 +--[[--
     2.7 +translated_string =             -- translated string
     2.8 +_(
     2.9 +  string_to_translate,          -- string to translate
    2.10 +  {
    2.11 +    placeholder_name1 = text1,  -- replace all occurrences of "#{placeholder_name1}" with the string text1
    2.12 +    placeholder_name2 = text2,  -- replace all occurrences of "#{placeholder_name2}" with the string text2
    2.13 +    ...
    2.14 +  }
    2.15 +)
    2.16 +
    2.17 +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.
    2.18 +
    2.19 +--]]--
    2.20 +
    2.21 +function _G._(text, replacements)
    2.22    local text = locale._get_translation_table()[text] or text
    2.23    if replacements then
    2.24      return (
    2.25 @@ -15,6 +29,7 @@
    2.26      return text
    2.27    end
    2.28  end
    2.29 +--//--
    2.30  
    2.31  --[[--
    2.32  cloned_table =  -- newly generated table
    2.33 @@ -38,11 +53,11 @@
    2.34  --//--
    2.35  
    2.36  -- load libraries (except "multirand", which must be loaded after forking)
    2.37 -extos       = require 'extos'
    2.38 -nihil       = require 'nihil'
    2.39 -mondelefant = require 'mondelefant'
    2.40 -atom        = require 'atom'
    2.41 -json        = require 'json'
    2.42 +_G.extos       = require 'extos'
    2.43 +_G.nihil       = require 'nihil'
    2.44 +_G.mondelefant = require 'mondelefant'
    2.45 +_G.atom        = require 'atom'
    2.46 +_G.json        = require 'json'
    2.47  require 'mondelefant_atom_connector'
    2.48  -- NOTE: "multirand" library is loaded in mcp.lua after forking
    2.49  
    2.50 @@ -67,6 +82,6 @@
    2.51  
    2.52  'config' is a global table, which can be modified by a config file of an application to modify the behaviour of that application.
    2.53  --]]--
    2.54 -config = {}
    2.55 +_G.config = {}
    2.56  --//--
    2.57  

Impressum / About Us