lua-users home
lua-l archive

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

On 19.10.2011 21:36, Petite Abeille wrote:

On Oct 19, 2011, at 9:08 PM, Philipp Janda wrote:

What happens if the name passed to require and the name passed to module differ?

Then hopefully you know what you are doing... or you have a typo...

Wouldn't require just return true

In case of name mismatch, require raises an exception...


local foo = require( 'baz' )

  module 'baz' not found

require raises an exception if "require-name" and "file-name" don't match, but it cannot handle a mismatch between "require-name" and "module-name", because it doesn't know "module-name".

$ mkdir extern
$ cat > extern/mod.lua
local print = print
_ENV = module( "mod" )

print( (...), _NAME )

function echo( ... )
  print( ... )

$ cat > main.lua
function module( aName, ... )
  local aModule = package.loaded[ aName ]
  if type( aModule ) ~= 'table' then
    aModule = {}
    aModule._M = aModule
    aModule._NAME = aName
aModule._PACKAGE = aName:sub( 1, aName:len() - ( aName:reverse():find( '.', 1, true ) or 0 ) )
    package.loaded[ aName ] = aModule
    for anIndex = 1, select( '#', ... ) do
      select( anIndex, ... )( aModule )
  return aModule

local mod = require( "extern.mod" )
mod.echo( "hello world" )

$ lua5.2 main.lua
extern.mod	mod
lua5.2: main.lua:17: attempt to index local 'mod' (a boolean value)
stack traceback:
	main.lua:17: in main chunk
	[C]: in ?

and the actual module ends up somewhere hidden in package.loaded?

Modules are named. They will end up under their assigned name.

Yes, they are named by require and put in package.loaded under "require-name" and they are named again by module and if "module-name" is different put in package.loaded again under "module-name".

It seems to me that the name parameter to module might be problematic if you don't set globals.

How so? This is not meant to prevent people from doing silly mistakes. Just to name their modules.

No, it enables people to make silly mistakes (s.a). It's a bad way to just name a module, because it forces users to edit the name if they want to move your module to a subdirectory -- why not use a comment instead.

Maybe you shouldn't unconditionally replace all non-table values from package.loaded in case some other module placed a function or a string there (which could happen if "require-name" and "module-name" differed).

Ah, yes... there is a sort of marker put in package.loaded by require to sort out circular dependencies during loading... I don't recall the details, but module circa 5.1 has all this sorted out... e.g.:

Not what I meant, but good point as well. What I meant is that *I* put functions in package.loaded, and I would hate it if some module overwrites my modules by doing module( "samename" ).

The proposed module-function doesn't mess with globals anymore, but it does mess with package.loaded

Well... "mess" might not be the right term... it simply sets it... just as module 5.1 does... module&  require work both in terms of package.loaded in tandem...

You are right, module 5.1 would also overwrite non-table modules. I didn't know that. What it should do is: create new table if package.loaded[ x ] is nil, reuse the table if package.loaded[ x ] is a table and raise an error otherwise.

and therefore should make sure that it does not disrupt other legitimate uses of package.loaded.


Good :-)