Strange LUA syntax questions
Jakobud opened this issue ยท 3 comments
I'm looking through your aux code, trying to understand how you did certain things. I see a lot of code I'm not familiar with. Syntax like this:
local query = O('name', filters.name)
and
for event in temp-S(.........)
Where are you getting this O(...)
function and also the temp-S(....)
function? Never seen anything like this before.
From my table recycling library. You're looking at a pretty old version of the code though. I have since simplified the module system and removed the flat imports so this should be a bit clearer.
"O" here is simply a function. "temp" is a "getter" which returns a table with "-" redefined through the metatable.
In either case this stuff is defined here https://github.com/shirsig/aux-addon/blob/master/libs/T.lua.
What temp means is that the table will be automatically reclaimed in the next onUpdate cycle.
O/A/S/T were helpers for defining tables that get them from the pool of recycled ones instead of creating new ones like the literal {}. They now have longer names.
Interesting. I'll look into your newer code some more. I like your use of modules and requiring. It's kinda like JavaScript modules in that way. I've never seen a WoW addon use that approach before. What is your opinion of this way vs. stuff the old Ace/Ace2/Ace3 did back in the Vanilla days?
My module system is inspired by the old and current lua module systems (http://lua-users.org/wiki/ModulesTutorial) with some additions like stronger encapsulation. The lua module system used with lua 5.0 (outside of wow) was also using a "module" function which used setfenv internally to change the file environment from the global environment to another table, though it didn't differentiate between public and private attributes. Anyone importing the module would get a shallow copy of that table which was mutable. I'm using metatables instead for an immutable public interface though it's a bit less performant. The modern lua module system doesn't use setfenv anymore (which doesn't exist anymore) but instead uses returning from a file to return a table containing the public interface (local M = {}; M.foo = 5; return M). My syntax for defining public attributes is inspired by that (M.foo =).
I've made pretty huge changes to my module system over time. At some point it had a lot more constraints (like also the private environment being immutable, throwing errors when accessing an attribute that doesn't exist) and features like a shortcut for defining getters and setters without metatables. Now I've removed all of that and made it more "lualike" and I'm pretty happy with it as it is.
I don't like the ace module system much. It doesn't do things I consider important for a module system (like encapsulation) and it does additional things I think don't belong in a module system like adding a lot of functions to the module table (it's kind of like extending a class that way).
The implementation of my module system (with the newest version at least) is super simple and all in this file: https://github.com/shirsig/aux-addon/blob/master/libs/package.lua.
When using "module" the environment, a mutable table which is set as the environment of the file with setfenv, is created and given four default attributes (_G, which holds the global table (just like in later lua versions), pass, which is a function that does nothing, _M, which is just a reference to the environment table itself and M, which is used to define public attributes. Also created it the "interface" which is an empty table with a metatable pointing to a data table containing the public attributes as its __index, so basically an immutable interface to the public attributes.