quickmeta keyword - jpbubble/NIL-isn-t-Lua GitHub Wiki

NIL relies on Lua, and has therefore just like Lua access to the metatable system.

This can either be done in the same way as it already works in Lua by creating a metatable and attaching that to an existing table, blah blah blah. If you really want to get really complex set up metatables with all the functionality the feature gives, then maybe that's the better option. If that's not the way you wanna go, but the metatables just need to quickly solve something, then you can use quickmeta in stead.

quickmeta class test1
	index
		return "Index test okay! (I got key "..key..")"
	end
	
	newindex
		print("You wanted to assign "..value.." to key?")
	end
	
	call
		print("You called?")
	end
	
end

var test
test = new test1
test.hello = "Hello world!"
print(test.yo)
test()


quickmeta group testgroup
	index
		return "The key was "..key
	end
	
	newindex
		print("The key was "..key.." and the value was a "..type(value).." containing "..tostring(value) )
	end
	
	tostring
		return "This group metatable"
	end
	
	call
		print("YOU RANG?")
	end
	
	gc
		print("Are you really destroying me?")
	end
end

testgroup.anumber = 10
testgroup.astring = "Hello World"
testgroup.memyselfandi = testgroup
testgroup()
print(testgroup.sleutel)

This was the source code written in NIL I used to test this feature. Now I REFUSE to call metatables classes, as it has nothing to do with how class based languages such as Java and C# work, but metatables are what you need to "fake" them (hey, psst.... to let you into a "secret", NIL actually uses meta tables to translate classes and groups).

Let's break this down. After the keyword "quickdata" NIL expects either "class" or "group". It's technically how NIL should pretend your meta table to be. By pretending to be a class, you can just use the "new" keyword (or leave it out when calling the table in Lua, see classes for more info on that), and a new table with the metatable in question attached to it will be created. When a "group" then you get a single variable on which the metatable has been attached, handy if that metatable only should be attached on that group.

Now metatables work with a kind of callback functions called "events" (that is how the Lua documentation calls them). In Lua all these are prefixed with two underscores, but in NIL's quickmeta feature you can leave those out (in fact NIL will throw an error if you put them in). All you can do in the quickmeta scope (Nerd's talk: which is only a scope for NIL's good, but won't be a scope in pure Lua, but since only event names are accepted, who cares) is name an event and then a function scope so you can script out the even will immediately be created.

Supported events

Before I break down all supported events a few notes:

  1. In quickmeta all events will have "self" as the variable Lua assigns the called table to. The variables "key" and "value" will be added as applicable. "call" will just use "infinity" for additional arguments.
  2. I only included the most obvious events right now. Others can be added when there's popular demand.
  3. NIL requires Lua 5.1 or higher, but the events "ipairs", "pairs" and "len" require Lua 5.2 or higher. While translating NIL will not notice the Lua version at all on these events and just translate them accordingly, however when running NIL in Lua 5.1 these events will simply be ignored by Lua. There is NOTHING AT ALL that NIL can do about that, and any bug reports on this matter will be closed immediately (repetitive reports can even lead to a ban from this repository).

index

Lua calls this when you call an index like this

print(mytable['hi']). 

The variable 'key' will hold the key (which was in this case the string 'hi').

newindex

Lua calls this when you assign to an index like this:

mytable["hi"]="Hello"

The variable "key" holds the key (in this case "hi") and the variable "value" will hold the value (in this case "Hello")

call

This event is invoked when you invoke the table as a function. Like this:

mytable()

quickmeta does not allow any argument assignment but you can just get the arguments with this code:

   var arguments
   arguments = { infinity }

gc

Invoked when a table holding this metatable is being destroyed by the Lua garbage collector. This event is extremely important when your metatable communicates with underlying C code (or whatever language you used to write the machine code Lua can communicate with), as Lua cannot know about any memory allocations by underlying C written APIs, you can use this to make sure the memory is released or open files are closed etc. etc. etc.... Even when your metatable only communicates within Lua, this can be important (which is why it's beyond me JavaScript has no support for it and a teacher of mine deemed it even "fortunate").

len

Called when this kind of code is used

print(#mytable)

Should therefore return a number Requires Lua 5.2 or higher. Lua 5.1 will ignore this event!

pairs and ipairs

Will make pairs and ipairs call this event in order to properly execute the 'for' loop they are in. Requires Lua 5.2 or higher. Lua 5.1 will ignore this event!

If you want any other event to be supported by NIL, simply write an issue, and I will see what I can do. The QuickMeta translator might, after all be one of the easiest things in the NIL source code, so it should be too much trouble.