Dofile Namespace Proposal

lua-users home

I find it unintuitive how dofile() operates within the global namespace rather than in the namespace of the caller.

For a real example, I have an application that embeds Lua and sets up a namespace for the user to run code under. The user may want to load and run yet other code, but dofile will not really work here for the user since dofile operates on and puts results into the global namespace that the calling code might not even see. The user might not even be aware of operating under a local namespace (nor should he, one might argue). Therefore, my application sets up for the user a new function myapp.import defined basically as follows:

function myapp.import(name)
  local f,e = loadfile(name)
  if not f then error(e, 2) end
  setfenv(f, getfenv(2))
  return f()

But one such user just reported that dofile does not do what they want (actually probably the second user), and I responded that they should use myapp.import instead, so there's obviously some confusion, and a good number probably aren't enough familiar with Lua namespaces to have understood why. Still, I wonder why dofile doesn't behave the way I want it to in the first place to avoid the issue.

RiciLake agreed, noting that the current behavior was a bit anachronistic (i.e. its semantics refer to older versions of Lua).

To reduce confusion, one option I have is to redefine dofile as such:

function dofile() error("Use myapp.import(name) instead of dofile(name)", 2)

Or, possibly with even less confusion, but with a small change to the built-in semantics, I could just redefine dofile within the local namespace as below. I tried to avoid a change in semantics, but maybe it is acceptable since the users probably shouldn't even be using the original semantics of modifying the global namespace when they have a perfectly good local one.

dofile = myapp.import

Alternately, this change could be made in Lua itself, but of course it might (does it?) break existing code. Another option might be to allow an additional parameter specifying the namespace, e.g. dofile("hello.lua", "caller"), but that goes a bit against the rule of thumb that the default behavior should satisfy the most common case (i.e. caller not global).

Details of Proposal:

RecentChanges · preferences
edit · history
Last edited November 28, 2006 2:56 am GMT (diff)