lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Jim Jones escribió:

-- I want to make definitions, such as the following,
-- illegal within my system;
-- All code needs to be contained within function definitions.
x = 5


Why make it illegal? It seems to me to make perfect sense.

If I were scripting in your system, I might well want to throw
some definitions into the beginning of the script file which
could be used by my functions. In fact, the power of Lua as
a configuration language derives exactly from the ability of
the configurer to execute and not just write configuration files.

The key is that you don't want those definitions to pollute
the global environment in which your system is running, and
furthermore you want certain globals to be visible to the
script files (along with the globals defined in the script
file). So you need to load and execute the script within
a specific environment. In Lua 5, I think (Wim will no doubt
correct me if this isn't right: I'm in a slightly different
mindset with respect to global environments) you should be
able to do this as follows:

their_definitions = loadfile "somefile.lua"
their_env = {
  math = math, -- give them the math library
  _STATVERSION = "2.3", -- tell them which version they're in
  -- etc.
}

-- Note: rather than adding math as a table to the scripting
-- environment you present, you might want to give them the
-- functions as (apparent) globals. But you don't want to
-- copy raw functions into their environment or the for
-- statement (below) will fail. So use an __index metamethod
-- instead: this could easily be generalised to handle more
-- than one library package:

setmetatable(their_env, {__index = math})
-- or
setmetatable(their_env, {
  __index = function(t, k)
  return my_utils[k] or math[k] or table[k] or string[k]
})

setfenv(their_definitions, their_env)

their_definitions() -- now run their script.

for k, v in their_env do
  if type(v) == "function" then
    add_to_function_menu(k)
  end
end

-- could be generalised to take arguments and return results
function run_their(function)
  their_env[function]()
end

-- ...

run_their "initialise"
-- do some statistics
run_their(menu_config.summary_function)

-- etc.