Thoughts on importing names from modules into a namespace

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Thoughts on importing names from modules into a namespace

Chris Marrin

I have been thinking about the idea of importing names, like what python
does with its various flavors of import statement. This goes along with
requiring modules that do not put themselves into the global namespace.

My requirements are this. I want to be able to require a module and then
import some or all of the properties in that module into a given
namespace. These names could import with the same name as in the module,
or they could use a common prefix to the module name, or could use a
completely different name. For simplicity, I only want to import
function properties. Here is what I came up with:

     function import(ns, mod, map)
         -- if we don't pass in a ns, use the fenv of the caller
         if ns == nil then
             ns = getfenv(2)
         end

         -- if map is a string, it is the prefix for every function
         local prefix = ""
         if type(map) ~= "string" then
             prefix = map
             map = { }
         elseif type(map) ~= "table" then
             map = { }
         end

         -- refactor map
         local newmap = { }
         for k,v in pairs(map) do
             if type(k) == "number" then
                 newmap[v] = v
             elseif type(k) == "string" then
                 newmap[k] = v
             end
         end

        -- import
         local all = #newmap == 0

         for k,v in pairs(mod) do
             if type(v) == "function" then
                 local key = newmap[v]
                 if key == nil then
                     if all then
                         key = k
                     end
                 end

                 if key ~= nil then
                     self[prefix..key] = v
                 end
             end
         end
     end

This allows you do do the following:

     import(nil, require "Node3D", { MyShape = "Shape", "Group" }

If the 'ns' param is nil, we use the fenv of the function containing the
import statement. If none is set, this will put the imported names into
the global object. In this example, only two functions from the module
are imported: "Shape" (which is renamed to "MyShape") and "Group".

I can also go:

     import(nil, require "Node3D")

to import everything, or:

     import(nil, require "Node3D", "my_")

to import everything and prefix each function name with "my_".

I think this gives pretty much all of the functionality I know about in
Python's import statement.

Any comments???

--
chris marrin                ,""$,
[hidden email]          b`    $                             ,,.
                         mP     b'                            , 1$'
         ,.`           ,b`    ,`                              :$$'
      ,|`             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`
"As a general rule,don't solve puzzles that open portals to Hell"'
Reply | Threaded
Open this post in threaded view
|

Re: Thoughts on importing names from modules into a namespace

Diego Nehab-3
hi,

> I have been thinking about the idea of importing names,
> like what python does with its various flavors of import
> statement. This goes along with requiring modules that do
> not put themselves into the global namespace.

The only problem with opening a package into the global
namespace is that, usually, packages refer to internal
symbols by referencing the namespace table directly. So, if
your package exports a variable, you will have made a copy
of it. Changes to that variable made in the global copy
won't  be visible to the package implementation.

Arguably this is a bad choice for the package interface
anyways (oh wait, LuaSocket does this). I am just letting
you know you might hit this kind of issue.

Regards,
Diego.
Reply | Threaded
Open this post in threaded view
|

Re: Thoughts on importing names from modules into a namespace

Chris Marrin
Diego Nehab wrote:

> hi,
>
>> I have been thinking about the idea of importing names,
>> like what python does with its various flavors of import
>> statement. This goes along with requiring modules that do
>> not put themselves into the global namespace.
>
>
> The only problem with opening a package into the global
> namespace is that, usually, packages refer to internal
> symbols by referencing the namespace table directly. So, if
> your package exports a variable, you will have made a copy
> of it. Changes to that variable made in the global copy
> won't  be visible to the package implementation.
>
> Arguably this is a bad choice for the package interface
> anyways (oh wait, LuaSocket does this). I am just letting
> you know you might hit this kind of issue.

Right. That's why I played it safe and only imported the functions.

--
chris marrin                ,""$,
[hidden email]          b`    $                             ,,.
                         mP     b'                            , 1$'
         ,.`           ,b`    ,`                              :$$'
      ,|`             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`
"As a general rule,don't solve puzzles that open portals to Hell"'
Reply | Threaded
Open this post in threaded view
|

Re: Thoughts on importing names from modules into a namespace

Diego Nehab-3
Hi,

> Right. That's why I played it safe and only imported the functions.

This happens even with functions. Replacing one of the
global functions will not cause the other exported functions
to use the replaced global one.

Regards,
Diego.