lua-users home
lua-l archive

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


I think I am very comfortable with the lua language itself. I am becoming more comfortable with the C API. Though I think with some inventiveness you could achieve a C-like const from this patch.


	rok = { key1 = true, key3 = true }
	mt = {
		__readonly = function(t,k,v)
			if rok[k] then error("Attempt to write to a read-only value") end
			rawset(t, k, v)
		end
	}

	mytab = { key1 = "val1", key2 = "val2", key3 = "val3" }
	setmetatable(mytab, mt)

	mytab["key1"] = "val1a"
	stdin:3: Attempt to write to a read-only value
	stack traceback:
	        [C]: in function 'error'
	        stdin:3: in function <stdin:2>
	        stdin:1: in main chunk
	        [C]: ?

	mytab["key2"] = "val2a"	
	
	print(mytab["key1"])
val1
	print(mytab["key2"])
val2a

Perhaps "ridiculous" is too strong a word. But I still feel that having to use a proxy table (which is not transparent in all circumstances without great effort to make it so) is a bit overkill when a simple code change to the table code would suffice. One could further simplify the above example by adding to the readonly code a test to see if the value of __readonly is a table and if so then only the keys that exist in that table would be immutable.

My goal with this patch was to provide a mechanism for "publishing" immutable data structures from C to Lua. While I probably could have suffered through the proxy table method, that would have required me to either: Translate the lua code required into C thus adding extra complexity and lines of code that have to be maintained
-or-
Use Lua code to do it in a separate file distributed with my project.

Neither seemed appealing to me.
When you compare the two approaches (proxy tables vs. my patch) you will find that with the patch:
It is far less code (Lua or C)
It is far less complex
It is transparent
It is just as flexible

All three of those get a '+' in my book. My biggest concern is the performance impact it may have. I'm only adding one extra check, but with very large datasets that may be one check too many. However, my guess is that in those circumstances the read-only table support wouldn't be needed, so it could be turned off in luaconf.h.

While the patch may not be the correct solution, but in my opinion if you are wanting simple (or even not so simple) immutable table support without having to jump through hoops it is the better solution. Proxy tables I'm sure have their uses, and if you don't mind the limitations and the lack of transparency then I'm sure they fit your bill. However, they didn't fit mine.


Thank you for your feedback,

Michael Grubb


On Nov 13, 2006, at 3:53 PM, Glenn Maynard wrote:

On Mon, Nov 13, 2006 at 09:41:35AM -0600, Michael Grubb wrote:
After doing a great amount of reading and experimentation I decided
that the existing methods for creating read-only tables in Lua 5.1
was untenable.
For such a simple thing it seemed rather ridiculous to have to use an
empty proxy-table along with or instead of redefinitions of the
several table related functions.
It seemed that there should be a simpler solution.  So I went about
poking around in the code and came up with a solution that works for
me.  You can find the patch below that adds Read-Only table support
to Lua-5.1.1.

Why does it seem ridiculous?  It's very simple; if it doesn't feel
simple, that may just be a symptom of not yet being comfortable with
the language.

That said, I do find a problem with proxy tables: they "break" pairs (),
operator #, and so on, so the resulting table is not transparently
interchangeable with the original.  This isn't specific to this use,
but to all uses of proxy tables, so I think it's sort of a flawed
paradigm as is ...

(One thing that proxy tables can do, which this patch can not, is C- like const, where the same object can have both const and non-const references
at the same time.  Your version is more like "immutable tables", which
can't be changed at all short of rawset.)

--
Glenn Maynard