lua-users home
lua-l archive

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



On 28/07/2010 22:39, Duck wrote:
I wish that Lua+C "combo-modules" wouldn't rely on loading the Lua code
first, and would build the core  code as an .so on its own.


I guess you're missing the actual problem. In fact, you can load 'socket.core' without any Lua code. For example (for sake of simplicity I'm calling 'luaopen_socket_core' directly although it is not the proper thing to do):

	#include <lua.h>
	#include <lauxlib.h>
	#include <luasocket.h>

	int main(int argc, char* argv[])
	{
		lua_State *L = luaL_newstate();
		luaL_openlibs(L);
		luaopen_socket_core(L);
		
		luaL_dostring(L,
			"s = assert(socket.tcp())"
			"assert(s:connect('www.lua.org', 80))"
			"assert(s:send('Hello, Lua!\\n'))"
			"print(s:receive())");
	
		lua_close(L);
		return 0;
	}

On 28 Jul 2010, at 21:04, Tim Channon wrote:
The workaround for static I use is very simple. Delete references to
load core from the static included .lua sources, no problem because
statically it is already loaded.

The thing about LuaSocket that might get people confused is that the 'luaopen_socket_core' function does not actually load a 'socket.core' module as it should. Instead, it loads part of the 'socket' module and does not set the 'package.loaded["socket.core"]' to indicate this module was loaded. Therefore, any later 'require "socket.core"' will fail even though this module is actually "loaded".

To fix this you can do like Tim Channon suggested above and avoid any 'require "socket.core"' in your code or you can simply fix what 'luaopen_socket_core' did with something like:

	package.loaded["socket.core"] = package.loaded["socket"]

Moreover, although the 'luaopen_socket_core' function does not load the 'socket' module completely it sets the 'package.loaded["socket"]' as if it does. This turns out that any following attempt to load the rest of the 'socket' module using a 'require "socket"' will be in vain. For example:

	Lua 5.1.4  Copyright (C) 1994-2008 Lua.org, PUC-Rio
	> require "socket.core"
	> require "socket"
	> s=assert(socket.connect("www.lua.org", 80))
	stdin:1: attempt to call field 'connect' (a nil value)
	stack traceback:
		stdin:1: in main chunk
		[C]: ?

To fix that, you can do something like the following before any 'require "socket"':

	package.loaded["socket"] = nil

Or better yet you can fix both problems by changing LuaSocket. For example:

	-- src/luasocket.old	2010-07-29 13:47:32.000000000 -0300
	+++ src/luasocket.c	2010-07-29 14:18:26.000000000 -0300
	@@ -89,7 +89,7 @@
	 static int base_open(lua_State *L) {
	     if (socket_open()) {
/* export functions (and leave namespace table on top of stack) */
	-        luaL_openlib(L, "socket", func, 0);
	+        luaL_openlib(L, "socket.core", func, 0);
	 #ifdef LUASOCKET_DEBUG
	         lua_pushstring(L, "_DEBUG");
	         lua_pushboolean(L, 1);

	--- src/socket.old	2010-07-29 14:10:07.000000000 -0300
	+++ src/socket.lua	2010-07-29 14:19:13.000000000 -0300
	@@ -11,6 +11,7 @@
	 local string = require("string")
	 local math = require("math")
	 local socket = require("socket.core")
+_G.socket = socket -- load this module in the same table of 'socket.core'
	 module("socket")

Most people never face these problems because they always call 'require "socket"' first and never invoke the 'luaopen_socket_core' function directly, which is either available through the 'package.cpath' or carefully preloaded. Instead, this function is called through a 'require "socket.core"' that will eventually set the 'package.loaded["socket.core"]' for it.

On 28 Jul 2010, at 22:32, Quae Quack wrote:
Could I put up the suggestion that the module adds nothing to the
global environment, but instead just returns the module? (that is, a
NULL argument to luaL_register)...

My impression is that 'luaopen_socket_core' creating a global 'socket' table is not a problem in this particular case thus avoiding such practice might not be the answer here.

--
Renato Maia
Computer Scientist
Tecgraf/PUC-Rio
__________________________
http://www.inf.puc-rio.br/~maia/