lua-users home
lua-l archive

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


Diego Nehab wrote:

...
Thanks for the help so far. My big issues still have to do with isolating namespaces. For instance, what about the problem I mention above? Are modules required by "b" isolated from those required in "a", like they are in Python?


No. All modules are available globally. If both "a" and "b" require"c",
both will share the same module. That said, Lua is powerful enough for
you to override this behavior. I believe VEnv, used with CGILua, does that. Once again, Lua gives you the power. If you need a sandbox, it can be done.

Yes, I agree that Lua has the power to do all this.

We are actually wrapping raw Lua in a declarative language called Emma (.ema), which looks a bit like VRML, but essentially generates Lua source, which then is loaded and run. The language lets you declare objects and their hierachical relationship. The resultant scene graph is just a big hierarchy of these objects. Each .ema file defines a new, top-level object, which can be embedded in other files, which form other objects, and so on.

What I want is to have each of these files form a namespace, which can have its own imported modules that are known in that file, but not outside. I am thinking that Lua environments are what I need to do this. But I am having trouble wrapping my head around them. For instance, I have a Lua function whose job it is to return a prototype object for a class. So Emma generates something like this:

    return ProtoNode {
        foo = function(self,a) self.b = a; globalThing = a end,
        b = 0
    }

When I execute this, I get back a ProtoNode object, which is essentially a Lua table with a C++ class embedded in it. This table also has a metatable with a __call metamethod to allow me to construct instances using the call syntax. I might put this proto into the global table called 'MyProto' so I can then say:

    local p = MyProto();

and I have an instance of MyProto. When I say instance, I mean that in a Javascript/Self prototype delegation way. 'p' has a 'prototype' property which points to MyProto. The metatable also has an __index metamethod which allows me to go:

    p.foo(12)
    print(p.b)

and have it print '12'. 'p' does not have a 'foo' or a 'b' property, but the __index metamethod looks in MyProto if it doesn't find them in 'p'. All pretty standard stuff. But this function also sets the global 'globalThing'.

The question is this. If I go:

    setfenv(1, { })
    return ProtoNode {
        foo = function(self,a) self.b = a end,
        b = 0
    }

the returned function will have new, empty environment. But will the 'foo' function have that same environment? Will 'globalThing' be set in my local environment instead? Or am I missing the point of setfenv()?

I think my brain is thinking about environments for Objects, so having environments on functions doesn't click with me.

Please forgive my naive questions. Any insights would be great...

--
chris marrin              ,""$, "As a general rule,don't solve puzzles
chris@marrin.com        b`    $  that open portals to Hell" ,,.
        ,.`           ,b`    ,`                            , 1$'
     ,|`             mP    ,`                              :$$'     ,mm
   ,b"              b"   ,`            ,mm      m$$    ,m         ,`P$$
  m$`             ,b`  .` ,mm        ,'|$P   ,|"1$`  ,b$P       ,`  :$1
 b$`             ,$: :,`` |$$      ,`   $$` ,|` ,$$,,`"$$     .`    :$|
b$|            _m$`,:`    :$1   ,`     ,$Pm|`    `    :$$,..;"'     |$:
P$b,      _;b$$b$1"       |$$ ,`      ,$$"             ``'          $$
 ```"```'"    `"`         `""`        ""`                          ,P`