Stringify object name in Lua - lua

In C I can do following:
#define S1(x) #x
#define S(x) S1(x)
#define foo(x) bar(x, S(x))
int obj = 3;
foo(obj);
void bar(int v, const char * name)
{
// v == 3
// name == "obj"
}
Can I do the same in Lua?
foo(barbar)
function foo(ob)
-- can I get "barbar"?
end

I think you could do something similar only by using a preprocessor which does something similar to your C preprocessor code. (The plain C compiler can't do something like that, too.)
Or write it explicitly:
foo(barbar, "barbar")

You Could do this, but as DeadMG suggested: don't.
A way would be:
function foo(bar)
return bar
end
print(foo(bar)) -- prints nil
setmetatable(_G,{__index=function(t,k)
if k:match"^_" then -- Don't use on system variables
return nil
else
return k
end
end})
print(foo(bar)) -- prints bar
But I would strongly comment against it, as this can have nasty side effects.

No, I don't believe you can. The use of such is dubious to begin with.

Related

How to make a custom ++, -=, += operator in lua?

How do I make a custom ++, -=, += operator in lua? Since it lacks increment/decrementing operators.
I'm trying to and here's my code:
local opTable = {}
debug.setmetatable(0, {
__call = function(a, op)
return opTable[op](a)
end
})
opTable["++", int + 1] -- The rest of the code works, this is the main line that's the problem.
local x = 2;
print(x++)
I also want to know how to do +=, and -=, or maybe how to do /= or *= and %=.
You can't make custom operators in Lua. It is not possible.
Your __call metamethod (if it actually works) would allow you to call x("++") (i.e. it allows you to call a number), not x++, and it would return x+1 without modifying x.
opTable["++", int + 1] makes no sense as a Lua statement. You probably wanted something like this:
opTable["++"] = function(int)
return int + 1
end
but it still won't do what you want. The syntax will still be x("++") and it will return x+1 and it won't modify x.

Lua: colon and dot function invocation acting differently

I initially came across this while developing my game in LOVE2D, and I can't figure out why.
As much as I know, x:foo() is just a syntactic sugar for x.foo(self) but combining this with other classes results in some weird behavior.
Basically, I have two programs
y = {}
function y:bar()
return self.b
end
x = {}
function x:foo()
return y.bar(self)
end
print(x.foo({b = 3}))
This prints 3 as expected
y = {}
function y:bar()
return self.b
end
x = {}
function x:foo()
return y:bar()
end
print(x.foo({b = 3}))
But this prints nil !!
I don't understand, why are these two programs printing different things?
x:foo() is syntactic sugar for x.foo(x)
which means that
function x:foo()
return y:bar()
end
is actually
function x:foo()
return y.bar(y)
end
look again at your use of self
function x:foo()
return y.bar(self) -- = y.bar(x)
end
function x:foo()
return y:bar() -- = y.bar(y)
end
x:foo() is just a syntactic sugar for x.foo(self)
This is correct in the context of a function definition but not as an expression.
function x.y.z:foo(a, b)
print(self, a, b)
end
is the same as
function x.y.z.foo(self, a, b)
print(self, a, b)
end
A function definition being set into a table field can be a method, that is with a :. Nested table fields are also allowed, for methods and non-methods, if the keys are strings that are valid Lua identifiers, as in x.y.z.
But
print(x.y().z:foo(a, b))
is the same as
local _ = x.y().z
print(_.foo(_, a, b))
With the method call syntax, the lefthand-side of : is an expression (x.y().z) that is evaluated only once.

In Lua, how to get the tail of an array without copying it?

I'm wokring with Lua 5.2, and for the sake of this question, assume that the tables are used exclusively as arrays.
Here's a function that returns the tail of an array (the array minus its first element):
function tail(t)
if # t <= 1 then
return nil
end
local newtable = {}
for i, v in ipairs(t) do
if i > 1 then
table.insert(newtable, v)
end
end
return newtable
end
For instance:
prompt> table.concat(tail({10, 23, 8}), ", ")
23, 8
However this is achieved by returning a new copy of the table. Is there a way to avoid the creation of a new table?
I am looking for the equivalent of C's returning a pointer to the next element (t++). Is it possible?
As already explained, this is normally impossible.
However, using metatables, you could implement a tail function that performs what you want without copying all the data, by referencing the original table. The following works for most operations in Lua 5.2, but for example not for table.concat:
function tail(t)
return setmetatable({}, {
__index = function(_, k) return t[k+1] end,
__newindex = function(_, k, v) t[k+1] = v end,
__len = function(_) return #t-1 end,
__ipairs = function(_) return
function(_, i)
if i+1==#t then return nil end
return i+1, t[i+2] end,
t, 0 end,
__pairs = function(t) return ipairs(t) end,
})
end
This is the nicest way I know to implement tail(). It makes one new table, but I don't think that's avoidable.
function tail(list)
return { select(2, unpack(list)) }
end
Nicol is correct that you can't reference a slice of an array, but there is an easier/shorter way to do what you want to do:
function tail(t)
local function helper(head, ...) return #{...} > 0 and {...} or nil end
return helper((table.unpack or unpack)(t))
end
print(table.concat(tail({10, 23, 8}), ", ")) will then print 23,8.
(added table.unpack or unpack to make it also work with Lua 5.2)
I am looking for the equivalent of C's returning a pointer to the next element (t++). Is it possible?
No. The only possible reason you could want this is performance. Such a feature is only found in low-level programming languages. Lua is a scripting language: performance is not such a priority that this would be implemented.
Just make another table like you're doing, or use table.remove to modify the original. Whichever works best for you. Remember: the big, important objects like tables and userdata are all stored by reference in Lua, not by value.
prapin's suggestion, to use metatables to present a view of the sequence, is roughly the way I'd do it. An abstraction that might help is defining a metatable for segments, which can be an 0-ary function that returns a pair of a table and an offset index - we are only using functions here to represent tuples. We can then define a metatable that makes this function behave like a table:
do
local tail_mt = {
__index = function(f, k) local t, i=f(); return t[k+i] end,
__newindex = function(f, k, v) local t,i=f(); t[k+1] = v end,
__len = function(f) local t,i=f(); return #t-i end,
__ipairs = function(f)
local t,i = f ()
return
function (_, j)
if i+j>=#t then
return nil
else
return j+1, t[i+j+1]
end
end, nil, 0
end,
}
tail_mt.__pairs = tail_mt.__ipairs -- prapin collapsed this functionality, so I do too
function tail (t)
if type(t) == "table" then
return setmetatable ( function () return t, 1 end, tail_mt )
elseif type(t) == "function" then
local t1, i = t ()
return setmetatable ( function () return t1, i+1 end, tail_mt )
end
end
end
With __index and __newindex metamethods, you can write code such as f[2]=f[1]+1.
Although this (untested) code doesn't endlessly create one-off metatables, it is probably less efficient than prapin's, since it will be calling thunks (0-ary functions) to get at their contents. But if you might be interested in extending the functionality, say by having more general views on the sequence, I think this is a bit more flexible.

Inline conditions in Lua (a == b ? "yes" : "no")?

Is there anyway to use inline conditions in Lua?
Such as:
print("blah: " .. (a == true ? "blah" : "nahblah"))
Sure:
print("blah: " .. (a and "blah" or "nahblah"))
If the a and t or f doesn't work for you, you can always just create a function:
function ternary ( cond , T , F )
if cond then return T else return F end
end
print("blah: " .. ternary(a == true ,"blah" ,"nahblah"))
of course, then you have the draw back that T and F are always evaluated....
to get around that you need to provide functions to your ternary function, and that can get unwieldy:
function ternary ( cond , T , F , ...)
if cond then return T(...) else return F(...) end
end
print("blah: " .. ternary(a == true ,function() return "blah" end ,function() return "nahblah" end))
You can usually do:
condition and ifTrue or ifFalse
but this isn't necessarily the best way to do it. The major reason why is because if ifTrue is a falsy value (some of the time), ifFalse will evaluate even if condition is a truthy value. One way to do it simply without much extra work is:
(condition and {ifTrue} or {ifFalse})[1]
which has the advantage of not only being an expression and not being subject to the problem of ifTrue being falsy which means it can handle all cases, but also has the advantage of short-circuiting (not evaluating the other expression). No need for extra functions or messing with complex aspects of Lua.
Although this question is fairly very old, I thought it would be fair to suggest another alternative that syntactically appears very similar to that of the ternary operator.
Add this:
function register(...)
local args = {...}
for i = 1, select('#', ...) do
debug.setmetatable(args[i], {
__call = function(condition, valueOnTrue, valueOnFalse)
if condition then
return valueOnTrue
else
return valueOnFalse
end
end
})
end
end
-- Register the required types (nil, boolean, number, string)
register(nil, true, 0, '')
And then use it like this:
print((true) (false, true)) -- Prints 'false'
print((false) (false, true)) -- Prints 'true'
print((nil) (true, false)) -- Prints 'false'
print((0) (true, false)) -- Prints 'true'
print(('') (true, false)) -- Prints 'true'
Note: For tables, however, you cannot use them directly with the above method. This is because each and every table has it's own independent metatable and Lua does not allow you to modify all tables at once.
In our case, an easy solution would be to convert the table into a boolean using the not not trick:
print((not not {}) (true, false)) -- Prints 'true'
You could just write the if statement in one line, it is no shorthand, inline or ternary operator stuff tho.
if (dummy) then
print("dummy is true")
end
is equal too
if (dummy) then print("dummy is true") end
Have fun
:D
local n = 12
do
local x = (n>15)
and print(">15")
or n>13
and print(">13")
or n>5
and print(">5")
end

D callbacks in C functions

I am writing D2 bindings for Lua. This is in one of the Lua header files.
typedef int (*lua_CFunction) (lua_State *L);
I assume the equivalent D2 statement would be:
extern(C) alias int function( lua_State* L ) lua_CFunction;
Lua also provides an api function:
void lua_pushcfunction( lua_State* L, string name, lua_CFunction func );
If I want to push a D2 function does it have to be extern(C) or can I just use the function?
int dfunc( lua_State* L )
{
std.stdio.writeln("dfunc");
}
extern(C) int cfunc( lua_State* L )
{
std.stdio.writeln("cfunc");
}
lua_State* L = lua_newstate();
lua_pushcfunction(L, "cfunc", &cfunc); //This will definitely work.
lua_pushcfunction(L, "dfunc", &dfunc); //Will this work?
If I can only use cfunc, why? I don't need to do anything like that in C++. I can just pass the address of a C++ function to C and everything just works.
Yes, the function must be declared as extern (C).
The calling convention of functions in C and D are different, so you must tell the compiler to use the C convention with extern (C). I don't know why you don't have to do this in C++.
See here for more information on interfacing with C.
It's also worth noting that you can use the C style for declaring function arguments.
Yes, your typedef translation is correct. OTOH have you looked at the htod tool?

Resources