Ensemble
Ensemble

Reputation: 230

Why make global Lua functions local?

I've been looking at some Lua source code, and I often see things like this at the beginning of the file:

local setmetatable, getmetatable, etc.. = setmetatable, getmetatable, etc..

Do they only make the functions local to let Lua access them faster when often used?

Upvotes: 12

Views: 6102

Answers (4)

mlepage
mlepage

Reputation: 2472

Another subtle benefit: It clearly documents which variables (functions, modules) are imported by the module. And if you are using the module statement, it enforces such declarations, because the global environment is replaced (so globals are not available).

Upvotes: 0

Nicol Bolas
Nicol Bolas

Reputation: 473437

Local data are on the stack, and therefore they do access them faster. However, I seriously doubt that the function call time to setmetatable is actually a significant issue for some program.

Here are the possible explanations for this:

  1. Prevention from polluting the global environment. Modern Lua convention for modules is to not have them register themselves directly into the global table. They should build a local table of functions and return them. Thus, the only way to access them is with a local variable. This forces a number of things:

    1. One module cannot accidentally overwrite another module's functions.

    2. If a module does accidentally do this, the original functions in the table returned by the module will still be accessible. Only by using local modname = require "modname" will you be guaranteed to get exactly and only what that module exposed.

    3. Modules that include other modules can't interfere with one another. The table you get back from require is always what the module stores.

  2. A premature optimization by someone who read "local variables are accessed faster" and then decided to make everything local.

In general, this is good practice. Well, unless it's because of #2.

Upvotes: 13

BMitch
BMitch

Reputation: 263636

In addition to Nicol Bolas's answer, I'd add on to the 3rd point:

  • It allows your code to be run from within a sandbox after it's been loaded.

If the functions have been excluded from the sandbox and the code is loaded from within the sandbox, then it won't work. But if the code is loaded first, the sandbox can then call the loaded code and be able to exclude setmetatable, etc, from the sandbox.

Upvotes: 5

daurnimator
daurnimator

Reputation: 4311

I do it because it allows me to see the functions used by each of my modules

Additionally it protects you from others changing the functions in global environment. That it is a free (premature) optimisation is a bonus.

Upvotes: 1

Related Questions