lua-users home
lua-l archive

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


Am 28.03.2015 um 05:16 schröbte Sean Conner:

   And when I run it, I get:

	1	a       table: 0x9b4b3c0
	2	_ENV    nil

   Um ... to me, this looks like a bug.  The *names* are in the right order,
but the *values* appear to have been swapped.  Or rather, load() just jammed
_ENV as the first upvalue, original order be damned!  The documentation for
string.dump() says:

	Returns a string containing a binary representation (a binary chunk)
	of the given function, so that a later load on this string returns a
	copy of the function (but with new upvalues). If strip is a true
	value, the binary representation is created without debug
	information about the function (local variable names, lines, etc.).

	Functions with upvalues have only their number of upvalues saved. When
	(re)loaded, those upvalues receive fresh instances containing nil. (You can
	use the debug library to serialize and reload the upvalues of a function in
	a way adequate to your needs.)

   Well, first off, this is wrong---all but the first upvalue are nil.  And if
you receive stripped code, you don't even get the names!  [1]  Okay, so it
seems I have to shuffle things around.

The manual says for `load`:
> If the resulting function has upvalues, the first upvalue is set to the value of env, if that parameter is given, or to the value of the global environment.

The other upvalues remain unset (aka `nil`). The 5.3 manual is explicit about this in the documentation for `load` (the 5.2 version was not):
> Other upvalues are initialized with nil.

And that pretty much sums up the behavior you are seeing.

Regarding the other upvalue issue:

The `local` keyword creates a unique local variable. Two pieces of code referring to the same local variable share that variable. Two functions referring to the same (outer) local variable share that upvalue. So if you don't see an explicit `local _ENV`, chances are that the `_ENV` upvalue is shared by all functions created in that scope. (There is one exception: `load`/`loadfile` also create new/unshared/unique upvalues.) If you want your function to have a unique `_ENV` upvalue after the fact, you can use the the `debug.upvaluejoin` trick mentioned elsewhere in the thread. Upvalues of C functions work differently, btw.

Philipp