Can Lua support case-insensitive method calls? - lua

I'm using Lua as a data description language for my C++ app. I have a bunch of C++ classes bound to Lua using SLB 2.0. I have methods bound such as 'SetPos' or 'SetName'. I specify the position or name (for example) using a table with values keyed as 'pos' or 'name'. I want to be able to take the key, prepend 'set', and call the method, if it exists (it may not). Is that possible? If so, any suggestions?
I know I could make my bound methods lower case, but I'd rather keep them the same as the methods they're bound to (that may be my fallback though). I could try to build the method name based on my naming standards, but case insensitivity is less error prone.
I feel there should be a tricky piece of Lua that could solve this using metatables, but I haven't been able to work it out myself.
Any suggestions?
Thanks!

Case insensitivity is not really something Lua handles. All table lookups and local variable accesses are ultimately case sensitive string compares.
The best solution would be to just accept that you're dealing with a case sensitive system, just like C++, and deal with it.
However, if you really want to, you can do this. The simplest way would be to put every possible case permutation of a name in your function table. So your function table would have this:
["setname"] = theFunction,
["Setname"] = theFunction,
["sEtname"] = theFunction,
["SEtname"] = theFunction,
...
You can of course automate this with a function that takes each name in the table and replicates its data based on the case permutations.
A more involved but easier to use mechanism would be to use the __index and __newindex metamethods along with the empty table trick.
function CreateCaseInsensitiveTable()
local metatbl = {}
function metatbl.__index(table, key)
if(type(key) == "string") then
key = key:lower()
end
return rawget(table, key)
end
function metatbl.__newindex(table, key, value)
if(type(key) == "string") then
key = key:lower()
end
rawset(table, key, value)
end
local ret = {}
setmetatable(ret, metatbl)
return ret
end
Instead of creating a table with {}, you create the table with this function call. The table should otherwise function as normal (though obviously member access will be slightly slower).

Related

Lua variable variables

I'm very new to Lua, I'm working with it on an io controller which has strict limits on script sizes so I need to work within these limits.
I have a number of relays which I am controlling (1-64). I need to switch off a relay when an event happens, but the relay I'm switching off can change.
I have a variable that holds the relay number and I need to turn off this relay.
I can achieve this using I statements:
if variable = 1 then
io.relay1=0 //Turns off the relay
end
else if variable = 2 then
io.relay2=0 //Turns off the relay
end
However, this will very quickly become a large script when repeated for the 64 relays. Is it possible to address the relay using the value of the variable as the relay name? Similar to the below:
io.relay{variable}=0 //Turns off the relay1/2/3/4/5 etc. depending on the value of variable
Alternatively, is there another way to keep the code compact?
Use
io["relay".. variable]=0
However, this creates a string every time.
If you can change how io works, a better solution would be to make io.relay a table and then simply do io.relay[variable]=0.
To avoid the string allocation issue that lhf's answer has, you could pre-generate a string table and index into that:
relay_names = {}
for k = 1,64 do
relay_names[k] = "relay"..tostring(k)
end
Then setting the IO states would look something like this:
io[relay_names[1]] = 1

Metamethod when accessing a key as mutable

__index is called when accessing as immutable :
local foo = bar["foo"];
__newindex is called when access as mutable an index that doesn't exist :
local bar = { }
bar["foo"] = 123 -- calls __newindex
bar["foo"] = 456 -- does NOT call __newindex
Is there a metamethod that can be called when accessing a key as mutable evey time, i.e not only if the key doesn't exist yet?
I would like to create a behavior so that when a users sets a key in a table, it calls a native method instead, regardless if the key already exists or not.
The standard way to do what you want is to use a proxy table, that is an empty table with suitable metamethods to access the actual table. Since the proxy is empty, the metamethods are called every time you get or set fields in it.
I am rather sure there are no such metamethods you ask for.
But you can try make a workaround to get what you want.
For example you can try to use the __call metamethod in this way:
local mt = {}
function mt.__call(tbl, key, val)
-- this is called every time you use bar(key, val)
tbl[key] = val
end
local bar = setmetatable({}, mt)
bar("foo", 123)
bar("foo", 456)
print(bar.foo)
Or you could use a function in some other way to achieve this.
Immutability doesn't exist in Lua, you just mean indexed accessing and assigning. Lua 5.3 states...
This event happens when table is not a table or when key is not
present in table.
...for both cases.
Your best option would be to store values in another table or subtable of yours.

Aerospike - Query with Multiple Filter parameters

I'm trying to query aerospike using multiple filters taking reference from this link.
I am able to query aerospike based on the given lua script for 1 filter parameter but stuck up with lua script when have to pass more than 2 filter parameters (for example passing two more parameters like age, gender with password).
This is my first time with lua.
Lua Script:
local function map_profile(record)
return map {name=record.name, password=record.password}
end
function check_password(stream,password)
local function filter_password(record)
return record.password == password
end
return stream : filter(filter_password) : map(map_profile)
end
Thanks in advance.
The filter function can have extra parameters and return a closure which can both access those, while still conforming to the expected stub of one parameter being the record, with a boolean return value.
local function filter_password(password)
return function(rec)
if rec['password'] and (type(rec['password']) == 'string') and
rec['password'] == password then
return true
end
return false
end
end
local function map_profile(record)
return map {name=record.name, password=record.password}
end
function check_password(stream,password)
return stream : filter(filter_password(password)) : map(map_profile)
end
However, the best way to query or scan for multiple filters these days (ever since release 3.12) is to use predicate filtering. In the majority of cases (unless you need to compare the values of two of the record's bins to each other in some way) you would skip UDFs and use the PredExp class (in the Java client, or its equivalent in another). You'd get back only those records that matched the filter, regardless of how complex of an expression you built. See the examples in the Aerospike Java client, or the C, C# and Go clients.
We developed SQL wrapper for Aerospike, that builds LUA code from your SQL query. It might be helpful to you.

Code re-use with Linq-to-Sql - Creating 'generic' look-up tables

I'm working on an application at the moment in ASP.NET MVC which has a number of look-up tables, all of the form
LookUp {
Id
Text
}
As you can see, this just maps the Id to a textual value. These are used for things such as Colours. I now have a number of these, currently 6 and probably soon to be more.
I'm trying to put together an API that can be used via AJAX to allow the user to add/list/remove values from these lookup tables, so for example I could have something like:
http://example.com/Attributes/Colours/[List/Add/Delete]
My current problem is that clearly, regardless of which lookup table I'm using, everything else happens exactly the same. So really there should be no repetition of code whatsoever.
I currently have a custom route which points to an 'AttributeController', which figures out the attribute/look-up table in question based upon the URL (ie http://example.com/Attributes/Colours/List would want the 'Colours' table). I pass the attribute (Colours - a string) and the operation (List/Add/Delete), as well as any other parameters required (say "Red" if I want to add red to the list) back to my repository where the actual work is performed.
Things start getting messy here, as at the moment I've resorted to doing a switch/case on the attribute string, which can then grab the Linq-to-Sql entity corresponding to the particular lookup table. I find this pretty dirty though as I find myself having to write the same operations on each of the look-up entities, ugh!
What I'd really like to do is have some sort of mapping, which I could simply pass in the attribute name and get out some form of generic lookup object, which I could perform the desired operations on without having to care about type.
Is there some way to do this to my Linq-To-Sql entities? I've tried making them implement a basic interface (IAttribute), which simply specifies the Id/Text properties, however doing things like this fails:
System.Data.Linq.Table<IAttribute> table = GetAttribute("Colours");
As I cannot convert System.Data.Linq.Table<Colour> to System.Data.Linq.Table<IAttribute>.
Is there a way to make these look-up tables 'generic'?
Apologies that this is a bit of a brain-dump. There's surely imformation missing here, so just let me know if you'd like any further details. Cheers!
You have 2 options.
Use Expression Trees to dynamically create your lambda expression
Use Dynamic LINQ as detailed on Scott Gu's blog
I've looked at both options and have successfully implemented Expression Trees as my preferred approach.
Here's an example function that i created: (NOT TESTED)
private static bool ValueExists<T>(String Value) where T : class
{
ParameterExpression pe = Expression.Parameter(typeof(T), "p");
Expression value = Expression.Equal(Expression.Property(pe, "ColumnName"), Expression.Constant(Value));
Expression<Func<T, bool>> predicate = Expression.Lambda<Func<T, bool>>(value, pe);
return MyDataContext.GetTable<T>().Where(predicate).Count() > 0;
}
Instead of using a switch statement, you can use a lookup dictionary. This is psuedocode-ish, but this is one way to get your table in question. You'll have to manually maintain the dictionary, but it should be much easier than a switch.
It looks like the DataContext.GetTable() method could be the answer to your problem. You can get a table if you know the type of the linq entity that you want to operate upon.
Dictionary<string, Type> lookupDict = new Dictionary<string, Type>
{
"Colour", typeof(MatchingLinqEntity)
...
}
Type entityType = lookupDict[AttributeFromRouteValue];
YourDataContext db = new YourDataContext();
var entityTable = db.GetTable(entityType);
var entity = entityTable.Single(x => x.Id == IdFromRouteValue);
// or whatever operations you need
db.SubmitChanges()
The Suteki Shop project has some very slick work in it. You could look into their implementation of IRepository<T> and IRepositoryResolver for a generic repository pattern. This really works well with an IoC container, but you could create them manually with reflection if the performance is acceptable. I'd use this route if you have or can add an IoC container to the project. You need to make sure your IoC container supports open generics if you go this route, but I'm pretty sure all the major players do.

Could I improve this method with duck typing?

Hopefully I haven't misunderstood the meaning of "duck typing", but from what I've read, it means that I should write code based on how an object responds to methods rather than what type/class it is.
Here's the code:
def convert_hash(hash)
if hash.keys.all? { |k| k.is_a?(Integer) }
return hash
elsif hash.keys.all? { |k| k.is_a?(Property) }
new_hash = {}
hash.each_pair {|k,v| new_hash[k.id] = v}
return new_hash
else
raise "Custom attribute keys should be ID's or Property objects"
end
end
What I want is to make sure that I end up with a hash where the keys are an integer representing the ID of an ActiveRecord object. I don't particularly enjoy having to iterate through the hash keys twice with all? to determine if I need to grab the ID's out.
Of course, I'll accept any other suggestions to improve this code as well :)
How you write this method should depend on whether you expect an exception to be thrown during the course of normal program execution. If you want a readable exception message because an end-user might see it, then throwing one manually makes sense. Otherwise, I'd just do something like this:
def convert(hash)
new_hash = {}
hash.each_pair { |k,v| new_hash[ k.is_a?(Integer) ? k : k.id ] = v }
return new_hash
end
This will accomplish exactly the same thing, and you'll still get an exception if an array key doesn't have an id field. Even better, this uses a little more duck typing because now anything that has an id field will be acceptable, which is better than explicitly checking for something being a Property. This makes your code more flexible, especially when unit testing.
We still have an explicit check for integer objects, but this kind of occasional special case is usually acceptable, especially when checking for built-in data types.
Duck typing is really just a nuanced version of polymorphism. In a statically typed language like Java you'd have to create an explicit interface that told the compiler all of the methods that a particular variable can accept. With a dynamic language like Ruby the interfaces still exist in an abstract sense, they're just implicit.
The problem is the fact that you're accepting two different data structures into one method. The way to make duck typing work is to require that all the objects that get passed to your method obey the same contract (i.e. it's always a hash of Integers to [Foo] objects.) The process of converting a hash with Property keys into the correct structure should be the job of the client code. That can be done very easily with a simple wrapper class or a conversion function consisting of just the body of your elseif clause.
Bottom line it's up to the guy calling the method to make sure his parameters all quack the way your method expects them to quack. If they don't, he's the one who need's to figure out how to make his turkey quack like a duck, not you.
What I want is to make sure that I end up with a hash where the keys are an integer representing the ID of an ActiveRecord object.
You should probably check for that when you're creating/inserting into the hash. You could try something like this:
h = {}
def h.put obj
self[obj.id]=obj
end
or maybe
h = {}
def h.[]= key, value
raise "hell" unless key == value.id
super
end

Resources