Why doesn't love2d use my custom-defined pairs metamethod? - lua

I have the following code in the file main.lua:
local table = {data={a=1,b=2,c=3}}
setmetatable(table, table)
function table:__pairs()
return pairs(self.data)
end
function table:__tostring()
return "a table"
end
print(table)
for e in pairs(table) do
print(e)
end
When I run lua main.lua I get the output
a table
a
b
c
When I run love ~/path/to/project I get the output
a table
__tostring
data
__pairs
Why does love use other metamethods correctly, but not pairs?
I have LOVE 11.3 (Mysterious Mysteries) and Lua 5.3.5

Love2D uses LuaJIT as its default interpreter, which is fixed to Lua 5.1. And while you can rebuild Love2D for the standard Lua 5.1 interpreter, making it use modern versions of the standard Lua interpreter would require substantial code hacking, since 5.2+ aren't backwards compatible.
And Lua 5.1 doesn't have the pairs metamethod.

Related

What's the , Lua equivalent of pythons endswith()?

I want to convert this python code to lua .
for i in range(1000,9999):
if str(i).endswith('9'):
print(i)
I've come this far ,,
for var=1000,9000 then
if tostring(var).endswith('9') then
print (var)
end
end
but I don't know what's the lua equivalent of endswith() is ,,, im writing an nmap script,,
working 1st time with lua so pls let me know if there are any errors ,, on my current code .
The python code is not great, you can get the last digit by using modulo %
# python code using modulo
for i in range(1000,9999):
if i % 10 == 9:
print(i)
This also works in Lua. However Lua includes the last number in the loop, unlike python.
-- lua code to do this
for i=1000, 9998 do
if i % 10 == 9 then
print(i)
end
end
However in both languages you could iterate by 10 each time
for i in range(1009, 9999, 10):
print(i)
for i=9, 9998, 10 do
print(i)
for var = 1000, 9000 do
if string.sub(var, -1) == "9" then
-- do your stuff
end
end
XY-Problem
The X problem of how to best port your code to Lua has been answered by quantumpro already, who optimized it & cleaned it up.
I'll focus on your Y problem:
What's the Lua equivalent of Python endswith?
Calling string functions, OOP-style
In Lua, strings have a metatable that indexes the global string library table. String functions are called using str:func(...) in Lua rather than str.func(...) to pass the string str as first "self" argument (see "Difference between . and : in Lua").
Furthermore, if the argument to the call is a single string, you can omit the parentheses, turning str:func("...") into str:func"...".
Constant suffix: Pattern Matching
Lua provides a more powerful pattern matching function that can be used to check whether a string ends with a suffix: string.match. str.endswith("9") in Python is equivalent to str:match"9$" in Lua: $ anchors the pattern at the end of the string and 9 matches the literal character 9.
Be careful though: This approach doesn't work with arbitrary, possibly variable suffices since certain characters - such as $ - are magic characters in Lua patterns and thus have a special meaning. Consider str.endswith("."); this is not equivalent to string:match".$" in Lua, since . matches any character.
I'd say that this is the lua-esque way of checking whether a string ends with a constant suffix. Note that it does not return a boolean, but rather a match (the suffix, a truthy value) if successful or nil (a falsey value) if unsuccessful; it can thus safely be used in ifs. To convert the result into a boolean, you could use not not string:match"9$".
Variable suffix: Rolling your own
Lua's standard library is very minimalistic; as such, you often need to roll your own functions even for basic things. There are two possible implementations for endswith, one using pattern matching and another one using substrings; the latter approach is preferable because it's shorter, possibly faster (Lua uses a naive pattern matching engine) and doesn't have to take care of pattern escaping:
function string:endswith(suffix)
return self:sub(-#suffix) == suffix
end
Explanation: self:sub(-#suffix) returns the last suffix length characters of self, the first argument. This is compared against the suffix.
You can then call this function using the colon (:) syntax:
str = "prefixsuffix"
assert(str:endswith"suffix")
assert(not str:endswith"prefix")

unwelcome if statement on luajit

lua 5.3.5 accepts the code below,
function isOdd (n)
if n & 1 == 1
then return true
else return false
end
end
print(isOdd(1), isOdd(2))
Why does luajit 2.0.5 refuse it?
line 2: 'then' expected near '&'
Because native bitwise operators are new to Lua 5.3, and LuaJIT is basically Lua 5.1. Use bit.band instead:
This module is a LuaJIT built-in — you don't need to download or install Lua BitOp. The Lua BitOp site has full documentation for all Lua BitOp API functions.
Please make sure to require the module before using any of its functions:
local bit = require("bit")
Source

Why can LuaJIT/Openresty use deprecated 'arg' language feature?

My understanding is that LuaJIT uses the Lua 5.1 syntax. In Lua 5.1, the 'arg' feature was removed from the language.
However, the following code works.
// test.lua
local function foo()
for k,v in pairs(arg) do
print(k .. " " .. v)
end
end
foo()
I would expect arg to be nil, but it exists and is doing the Lua 5.0 functionality.
Running resty test.lua hello world results in:
0 test.lua
1 hello
2 world
-1 /usr/local/bin/resty
Why does this work? Are there exceptions to the 5.1 syntax that Openresty and LuaJIT can use?
You're mixing two different things.
The arg table you see here is not a "deprecated Lua feature". It's a table of arguments given to Lua interpreter, explicitly pushed to the global arg variable by the interpreter, and it's still there in the latest Lua and LuaJIT versions.
The feature you've heard was removed - that's about replacing implicit arg parameter with vararg expression in vararg functions. I.e. the extra arguments to functions now available through ... syntax, and not as a table of collected values through implicit arg parameter.

Running a lua script as a gel script

I have the following lua script that separates a string in its proper words:
names = "aa bb cc dd"
words = {}
for word in names:gmatch("%w+") do table.insert(words, word) end
for k,v in pairs(words) do print(k,v) end
I am using a program called Graphite, which is a platform for computer graphics and more. In its readme it is written:
You can write a LUA script and run it with Graphite. Just load the
script using GEL -> execute file.
Having very small experience with LUA and zero knowledge about what GEL is, I am having trouble running a script. After some googling I found this: http://gema.sourceforge.net/new/gel.shtml#3_1 ,
but it is still not so clear to me what the connection between gel and lua is. In this website it is described as: a Lua binding for Gema, a general purpose text processing utility.
The above script for example works as intended in the lua interpreter. On the other hand, when I try to execute it as a .gel script (because the software mentioned above requires a .gel script) it returns a syntax error.
Any idea on how to make it run as a .gel script? Or any other comment that might help?
If you read the documentation more closely, you'll notice:
Embed the lua functions in the gema file using the new syntax "![" "!]"
They also have an example provided:
![
function inflog(x)
if x>0 then return math.log(x)
else return "-infty"
end
end
!]
<N>=#lua{return inflog($0)}
Following the same example, the following should work:
![
function split(names)
words = {}
for word in names:gmatch("%w+") do table.insert(words, word) end
for k, v in ipairs(words) do print(k, v) end
return words
end
!]
<N>=#lua{return split($0)}

How to correctly redefine print in Lua 5.3?

I frequently use print function for debugging in conjunction with os.exit(). I don't want to type os.exit() each time I use print, so I want to redefine this function.
> function pprint(...)
>> for _,a in ipairs(arg) do
>> print(a)
>> end
>> os.exit()
>> end
> pprint('hello',1,2,3)
hello
1
2
3
[johndoe#dell-john ~]$
Although this works in Lua 5.1, it does not work in Lua 5.3 and, for some reason, Torch. I looked up the Lua 5.3 docs for "triple dots" expression but couldn't find the reference on how to access ... arguments. Can you explain what was changed and how to redefine print for Lua 5.3?
Automatic creation of the arg table for vararg functions was deprecated in Lua 5.1 and removed in Lua 5.2.
As mentioned by Egor, use
for _,a in ipairs({...}) do
instead of
for _,a in ipairs(arg) do
Or add
local arg={...}
at the start of the function.
for _,a in ipairs({...}) do is wrong ,it does not support nil
right rewrite
local arg = table.pack(...)
for i = 1 ,arg.n do
old_print(arg[i])
end

Resources