lua-users home
lua-l archive

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

On Sat, 13 Feb 2010 13:38:55 +0100
spir <> wrote:

> On Fri, 12 Feb 2010 13:13:05 +0100
> spir <> wrote:

> @ Tom: While I think I understand the use of weak tables, I don't get why/how it should solve the issue.

Sorry, I think I get it now: maybe you meant reversing the issue by storing _custom_ file attributes in a separate and common (and weak) table. This would indeed be a good solution. (In fact, it would even allow me implementing another idea of "virtual" files, not yet open).
Still, for this to work, I need to set a metatatable for Lua files that redirects attribute lookup to the table. (To have a single metatable, I implemented __index and __newindex as function; they could point to the file attribute subtable, but then there would be a distinct metatable for each file.)
Lua files don't seem to have any metatable, so I created one:

-- common weak table for custom file attributes
fileAttributes = setmetatable({}, {__mode='k'})
-- definition of File
File.tostring = function(f) return 'File"'..fileAttributes[f].name..'"' end
File.getAttribute = function(f,k)
	return fileAttributes[f][k]
File.setAttribute = function(f,k,v)
	fileAttributes[f][k] = v
File.create = function(_,name)
	local f =,'r')
	print(f)			-- debug
	fileAttributes[f] = {name=name}
	debug.setmetatable(f, file_mt)
	return f
File_mt = {__call=File.create}
setmetatable(File, File_mt)
-- common metatable for files
file_mt = {
	__index = File.attribute,
	__newindex = File.getAttribute,
	__tostring = File.tostring,
-- example
test2 = function()
	f = File"test"
	print (f)
	for i=1,4 do print(f:read()) end

* When I don't assign the metatable to files, all works fine, except indeed I have no access to custom attrs. Output is:
file (0x88ac048)
file (0x88ac048)
-- test --

* When I try to assign the metatable, I get an error because Lua files are userdata:
file (0x8721048)
lua: fileProxy.lua:52: bad argument #1 to 'setmetatable' (table expected, got userdata)
stack traceback:
	[C]: in function 'setmetatable'
	fileProxy.lua:52: in function 'File'
	fileProxy.lua:66: in function 'test2'
	fileProxy.lua:71: in main chunk
	[C]: ?

* When I force it using debug.setmetatable, attribute access works fine, but then builtin method call fails! I do not understand what the issue is:

file (0x8500048)
lua: fileProxy.lua:67: attempt to index global 'f' (a userdata value)
stack traceback:
	fileProxy.lua:67: in function 'test2'
	fileProxy.lua:70: in main chunk
	[C]: ?

Line 67 is "for i=1,5 do print(f:read()) end"
It seems the metatable in a way "hides" builtin methods. ?


la vita e estrany