What is the difference between lua_getmetatable and luaL_getmetatable - lua

Lua API has a function lua_getmetatable which will fetch the table with metafunctions if the value has one.
Lua auxiliary library (which is part of lua API) has another function luaL_getmetatable which is a macro that will fetch a value from LUA_REGISTRYINDEX.
But another function from this library luaL_getmetafield with similar name does a completely different thing - it will look for a method in the get_metatable's location.
Why is there two different locations?
When is each metatable used?

lua_getmetatable gets the metatable associated with the given object. This is a fundamental feature; if this function didn't exist, there would be no way to access the metatable for a given object.
luaL_getmetatable is part of a convention for giving types to userdata (C objects that can be accessed from Lua) or classes of tables. In this convention you add tables to the registry with luaL_newmetatable, and then use these tables to represent the metatables for different userdata/table types (when you need them you can read them from the registry and set them with luaL_setmetatable).
This is a convenience feature only; and you do not need to follow this convention if you don't want to. Everything will still work if you place the metadata tables somewhere that isn't in the registry and bind them to your userdata with lua_setmetatable. That said, if the luaL_*metatable functions didn't exist, where would you put the tables that you were using to represent the different userdata/table types; and how would you find them again when you needed them for a second time? You could definitely solve this problem in a different way, but why not use the pre-built convention if it works for you.

Related

Referencing Two Separate Variables by One Name/Call

I am new to Lua and am not sure if this is even possible.
Referencing two separate variables by one name/call,
i.e,
local pieces = game.Workspace.Part1 In Addition to game.Workspace.Part2
Both are specific objects, not values.
short answer:
No
What you want to do is not possible in Lua, or in any other programming language I know of. What you want to achieve however, can easily be done.
The most straight-forward solution would be to just check your condition for either of the two values. If you need to do this often, you could make a function that checks the condition on both values, and if it happens with many different values, you can even write a function that returns another closure that checks your condition for two upvalues.
If what you care about is not so much easily checking a condition for both values, but to store them together in a semantically meaningful way, you can just put both of them in a table like {first = game.Workspace.Part1, second = game.Workspace.Part1}, and apply your condition to its elements first and second instead of the object itself.

Table of reference to variables in Lua

I'm trying to keep track of various variables in a big Lua code base, for logging and analytics purposes.
Ideally I want to create a register function that registers an existing global variable and keeps a reference to that variable (can be anything from numbers, booleans or other tables) in a table.
This table will then be used to loop on and output the values of the registered variables at certain points of the execution.
I won't have control over what type of variables are used, and cannot change how those variables are setup. So I don't have the option of changing those variables to tables and such.
What would be the best approach in Lua?

Erlang ets:insert_new for bag

In my code I want to take advantage of ETS's bag type that can store multiple values for single key. However, it would be very useful to know if insertion actually inserts a new value or not (i.e. if the inserted key with value was or was not present in the bag).
With type set of ETS I could use ets:insert_new, but semantics is different for bag (emphasis mine):
This function works exactly like insert/2, with the exception that instead of overwriting objects with the same key (in the case of set or ordered_set) or adding more objects with keys already existing in the table (in the case of bag and duplicate_bag), it simply returns false.
Is there a way to achieve such functionality with one call? I understand it can be achieved by a lookup followed by an optional insert, but I am afraid it might hurt performance of concurrent access.

What is a "tag" in Lua 4.0?

I was reading the Lua 4.0 manual and I came across this "tag" thing but I have no idea what it is referring to.
http://www.lua.org/manual/4.0/manual.html#3
That's the section where it mentions it but I still have no idea what the manual is talking about.
TL;DR: Tags are the precursor to modern-day meta-tables. Where now the event-handler-pairs are stored directly in the meta-table using normal table-manipulation, as it is a normal table, then we used those tags, normal though unique numbers, and special data-structures, which restricted the events we could set, and had a different interface.
One of the disadvantages of tags was they could not be garbage-collected as they were normal numbers, and thus their associated data could not either.
Quoting the important parts of section 3 "types and tags":
Besides a type, all values also have a tag.
Each of the types nil, number, and string has a different tag. All values of each of these types have the same pre-defined tag. As explained above, values of type function can have two different tags, depending on whether they are Lua functions or C functions. Finally, values of type userdata and table can have variable tags, assigned by the programmer (see Section 4.8). The tag function returns the tag of a given value. User tags are created with the function newtag. The settag function is used to change the tag of a table (see Section 6.1). The tag of userdata values can only be set from C (see Section 5.7). Tags are mainly used to select tag methods when some events occur. Tag methods are the main mechanism for extending the semantics of Lua (see Section 4.8).
So, think of tags as unique ids.
Every value has a tag, depending on its type:
All values of the types nil, number, string, function (C-flavor), function (Lua flavor) have a type-specific tag set on the C side.
All values of the types table and userdata have tags too, but those are set by the programmer for each value indepent from any other.
tag returns the tag, settag sets it for table and userdata, newtag creates a new one.
And looking at section 4.8 "tag methods", we understand that those unique ids are just used for comfortably associating all values of the same Lua type (or for tables and userdatas of the same semantic user-type) with special behavior:
Lua provides a powerful mechanism to extend its semantics, called tag methods. A tag method is a programmer-defined function that is called at specific key points during the execution of a Lua program, allowing the programmer to change the standard Lua behavior at these points. Each of these points is called an event.
The tag method called for any specific event is selected according to the tag of the values involved in the event (see Section 3). The function settagmethod changes the tag method associated with a given pair (tag, event). Its first parameter is the tag, the second parameter is the event name (a string; see below), and the third parameter is the new method (a function), or nil to restore the default behavior for the pair. The settagmethod function returns the previous tag method for that pair. A companion function gettagmethod receives a tag and an event name and returns the current method associated with the pair.
Which just boils down to settagmethod and gettagmethod being used to manage a mapping from tag+event to handler, and the runtime using that as an extension point.
As LHF mentions below, there's a wealth of additional detail and history in The evolution of Lua, for example how the tag-methods evolved from the previous extension-mechanism of "fallbacks", which did not support different behavior for separate groups of values, instead being global.

SPROC to update record: how to handle unchanged values

I'm calling a update SPROC from my DAL, passing in all(!) fields of the table as parameters. For the biggest table this is a total of 78.
I pass all these parameters, even if maybe just one value changed.
This seems rather inefficent to me and I wondered, how to do it better.
I could define all parameters as optional, and only pass the ones changed, but my DAL does not know which values changed, cause I'm just passing it the model - object.
I could make a select on the table before updateing and compare the values to find out which ones changed but this is probably way to much overhead, also(?)
I'm kinda stuck here ... I'm very interested what you think of this.
edit: forgot to mention: I'm using C# (Express Edition) with SQL 2008 (also Express). The DAL I wrote "myself" (using this article).
Its maybe not the latest state of the art way (since its from 2006, "pre-Linq" so to say but Linq works only for local SQL instances in Express anyways) of doing it, but my main goal was learning C#, so I guess this isn't too bad.
If you can change the DAL (without changes being discarded once the layer is "regenerated" from the new schema when changes are made), i would recomend passing a structure containing the column being changed with values, and a structure kontaing key columns and values for the update.
This can be done using hashtables, and if the schema is known, should be fairly easy to manipulate this in the "new" update function.
If this is an automated DAL, these are some of the drawbacks using DALs
You could implement journalized change tracking in your model objects. This way you could keep track of any changes in your objects by saving the previous value of a property every time a new value is set.This information could be stored in one of two ways:
As part of each object's own private state
Centrally in a "manager" class.
In the first solution, you could easily implement this functionality in a base class and have it run in all model objects through inheritance.
In the second solution, you need to create some kind of container class that will keep a reference and a unique identifier to any model object that is created and record all changes in its state in a central store.This is similar to the way many ORM (Object-Relational Mapping) frameworks achieve this kind of functionality.
There are off the shelf ORMs that support these kinds of scenarios relatively well. Writing your own ORM will leave you without many features like this.
I find the "object.Save()" pattern leads to this kind of behavior, but there is no reason you need to follow that pattern (while I'm not personally a fan of object.Save(), I feel like I'm in the minority).
There are multiple ways your data layer can know what changed and most of them are supported by off the shelf ORMs. You could also potentially make the UI and/or business layer's smart enough to pass that knowledge into the data layer.
Two options that I prefer:
Generating/hand coding update
methods that only take the set of
parameters that tend to change.
Generating the update statements
completely on the fly.

Resources