lua-users home
lua-l archive

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


On Sat, 13 Feb 2010 14:37:55 +0000
Duncan Cross <duncan.cross@gmail.com> wrote:

> On Sat, Feb 13, 2010 at 2:15 PM, spir <denis.spir@free.fr> wrote:
> > Lua files don't seem to have any metatable, so I created one:
> 
> No, they do!
> 
> > It seems the metatable in a way "hides" builtin methods. ?
> 
> Lua files are userdata objects, and as such the only way they can
> *have* methods is if they have a metatable that includes an __index
> table or function. That is the only mechanism that allows for it. If
> you get the metatable of a file you will see that it includes an
> __index table, and this is what contains all the method functions
> (read, write, close, etc.).
> 
> -Duncan

Thank you very much, Duncan. For any reason (typo?) when I previously tried to get the builtin metatable for files, I always got nil (even when using debug). Now, all works fine. Below an example, FWIW:

-- common weak table for custom file attributes
fileAttributes = setmetatable({}, {__mode='k'})

-- common metatable for files, redefined as File
f = io.open("test",'r') ; File = getmetatable(f) ; f:close()
File.__index = function(f,k)
	v = File[k]
	-- case builtin method
	if v then
		return v
	-- case custom attribute
	else
		return fileAttributes[f][k]
	end
end
File.__newindex = function(f,k,v)
	fileAttributes[f][k] = v
end
File.__tostring = function(f)
	return 'File"'..fileAttributes[f].name..'"'
end
File.__call = function(_,name)	-- creation of new file
	local f = io.open(name,'r')
	fileAttributes[f] = {name=name}
	debug.setmetatable(f, File)
	return f
end

-- File's own metatable
File_mt =  {__call=File.__call}
setmetatable(File, File_mt)

-- example
test1 = function()
	f = File"test"
	print (f)
	for i=1,4 do print(f:read()) end
	f:close()
end
test1()

==>

File"test"
-- test --
foo
bar
nil

To write what I initially intended to code, I still need a way to really delegate builtin method calls to Lua files. This does not seem to be possible, since the "self" object is wrong (the proxy instead of the file), except by dispatching method per method as Steve suggested. The metatable thus must be a distinct "type" so that the builtin one does not help anymore, unfortunately.

Denis
________________________________

la vita e estrany

http://spir.wikidot.com/