i'm new in Lua and want to use LuaDate Library for my Project on a OpenWrt System.
It seems, that Metamethods not working correctly with Lua 5.1.4, which is the version
installed in OpenWrt Backfire. If i try the following code with Lua 5.1.5 on osx:
date = require('date')
print(date('2013-12-14T00:07:04') < date('2013-12-14T12:07:01'))
true is printed. If i run the code on OpenWrt with LUA 5.1.4, a error is thrown:
lua: test.lua:3: attempt to compare two table values
stack traceback:
test.lua:3: in main chunk
[C]: ?
Is it possible, to fix this issue? For example call the Metamethods directly?
You are getting a table from the date lib, You can use < for nothing but numbers. Better to get key names and value names of a simple date value to understand which members it has.
for k, v in pairs(date("2013-12-14T00:07:04")) do
print("KEY: "..k..", VALUE: "..v)
end
After getting keys and values, you can use something like this:
local d = date("2013-12-14T00:07:04")
local num = 0
num = d.seconds
num = num + d.minutes * 60
num = num + d.hours * 3600
if (num < 1500) return end
Related
I am trying to find a solution to the problem "Two Sum" if you recognize it , and I've run into a problem and I cannot figure it out (Lua)
Code:
num = {2,7,11,15}
target = 9
current = 0
repeat
createNum1 = tonumber(num[math.random(1,#num)])
createNum2 = tonumber(num[math.random(1,#num)])
current = createNum1 + createNum2
until current == target
print(table.find(num,createNum1), table.find(num,createNum2))
Error:
lua5.3: HelloWorld.lua:9: attempt to call a nil value (field 'find')
stack traceback:
HelloWorld.lua:9: in main chunk
[C]: in ?
Thank you!
Lua has no table.find function in its very small standard library; just take a look at the reference manual.
You could implement your own table.find function, but that would just be monkey-patching an overall broken algorithm. There is no need to use a probabilistic algorithm that probably runs in at least quadratic time if there only is one pair of numbers that adds up to the desired number. Instead, you should leverage Lua's tables - associative arrays - here. First build an index of [number] = last index:
local num = {2,7,11,15}
local target = 9
local idx = {}
for i, n in ipairs(num) do idx[n] = i end
then loop over the numbers; given a number m you just need to look for target - m in your idx lookup:
for i, n in ipairs(num) do local j = idx[target - n]; if j then print(i, j) break end end
if you want to exit early - sometimes without building the full idx table - you can fuse the two loops:
local idx = {}
for i, n in ipairs(num) do
local j = idx[target - n]
if j then
print(j, i)
break
end
idx[n] = i
end
other solutions exist (e.g. using sorting, which requires no auxiliary space), but this one is elegant in that it runs in O(n) time & O(n) space to produce a solution and leverages Lua's builtin data structures.
I was excited to learn that, as of Lua 5.4, Lua supports constant (const) and to-be-closed (close) variables! However, upon testing these keywords, they don't seem to do anything at all. I wrote the following code to sample the features to get a better grasp of their exact usage:
function f()
local const x = 3
print(x)
x = 2
print(x)
end
f()
function g()
local close x = {}
setmetatable(x, {__close = function() print("closed!") end})
end
g()
I titled the file constCheck.lua and ran it with lua constCheck.lua. The output is as follows:
3
2
I was expecting an error on my call to f(), or at least for it to print 3 twice, instead it seemed to reassign x with no issue at all. Further, I was expecting the call to g() to print out "closed!" when x left scope at the end of the function, but this did not happen. I can't find very many examples of these keywords' usage. Am I using them properly? Do they work?
Note: lua -v => Lua 5.4.0 Copyright (C) 1994-2020 Lua.org, PUC-Rio
This is <const> not const, and <close> not close
See https://lwn.net/Articles/826134/
do
local x <const> = 42
x = x+1
end
-- ERROR: attempt to assign to const variable 'x'
And some example https://github.com/lua/lua/blob/master/testes/code.lua#L11
local k0aux <const> = 0
https://github.com/lua/lua/blob/master/testes/files.lua#L128
local f <close> = assert(io.open(file, "w"))
From the Lua 5.4 Reference Manual : 3.3.7 - Local Declarations
Each variable name may be postfixed by an attribute ( a name between angle brackets):
attrib ::= [‘<’ Name ‘>’]
There are two possible attributes: const, which declares a constant
variable, that is, a variable that cannot be assigned to after its
initialization; and close, which declares a to-be-closed variable
So you would have to write local x <const> = 3 for example.
Your code local const x = 3 is equivalent to
local const = nil
x = 3
So you're actually creating a local nil value const and a global number value x.
I'm using luacheck (within the Atom editor), but open to other static analysis tools.
Is there a way to check that I'm using an uninitialized table field? I read the docs (http://luacheck.readthedocs.io/en/stable/index.html) but maybe I missed how to do this?
In all three cases in the code below I'm trying to detect that I'm (erroneously) using field 'y1'. None of them do. (At run-time it is detected, but I'm trying to catch it before run-time).
local a = {}
a.x = 10
a.y = 20
print(a.x + a.y1) -- no warning about uninitialized field y1 !?
-- luacheck: globals b
b = {}
b.x = 10
b.y = 20
print(b.x + b.y1) -- no warning about uninitialized field y1 !?
-- No inline option for luacheck re: 'c', so plenty of complaints
-- about "non-standard global variable 'c'."
c = {} -- warning about setting
c.x = 10 -- warning about mutating
c.y = 20 -- " " "
print(c.x + c.y1) -- more warnings (but NOT about field y1)
The point is this: as projects grow (files grow, and the number & size of modules grow), it would be nice to prevent simple errors like this from creeping in.
Thanks.
lua-inspect should be able to detect and report these instances. I have it integrated into ZeroBrane Studio IDE and when running with the deep analysis it reports the following on this fragment:
unknown-field.lua:4: first use of unknown field 'y1' in 'a'
unknown-field.lua:7: first assignment to global variable 'b'
unknown-field.lua:10: first use of unknown field 'y1' in 'b'
unknown-field.lua:14: first assignment to global variable 'c'
unknown-field.lua:17: first use of unknown field 'y1' in 'c'
(Note that the integration code only reports first instances of these errors to minimize the number of instances reported; I also fixed an issue that only reported first unknown instance of a field, so you may want to use the latest code from the repository.)
People who look into questions related to "Lua static analysis" may also be interested in the various dialects of typed Lua, for example:
Typed Lua
Titan
Pallene
Ravi
But you may not have heard of "Teal". (early in its life it was called "tl"); .
I'm taking the liberty to answer my original question using Teal, since I find it intriguing.
-- 'record' (like a 'struct')
local Point = record
x : number
y : number
end
local a : Point = {}
a.x = 10
a.y = 20
print(a.x + a.y1) -- will trigger an error
-- (in VS Code using teal extension & at command line)
From command line:
> tl check myfile.tl
========================================
1 error:
myfile.tl:44:13: invalid key 'y1' in record 'a'
By the way...
> tl gen myfile.tl'
creates a pure Lua file: 'myfile.lua' that has no type information in it. Note: running this Lua file will trigger the 'nil' error... lua: myfile.lua:42: attempt to index a nil value (local 'a').
So, Teal gives you a chance to catch 'type' errors, but it doesn't require you to fix them before generating Lua files.
A beginner's question about Lua and metatables, with a example as simple as an Hello‑World, involving the len event, which unfortunately does not returns the expected result (I'm using Lua 5.1 installed from Ubuntu's official repository).
The case
Here is the example:
Test_Type = {};
function Test_Type.__len (o)
return 1;
end;
function new_test ()
local result = {};
setmetatable(result, Test_Type);
return result;
end;
do
local a_test = new_test();
print (#a_test);
print(getmetatable(a_test).__len(a_test));
end;
And the result I get:
0
1
I was expecting the first print statement to display 1, but it displays 0, to my big surprise.
What did I missed?
According to Lua Reference Manual — Metatables and Metamethods, the # is equivalent to this:
function len_event (op)
if type(op) == "string" then
return strlen(op) -- primitive string length
else
local h = metatable(op).__len
if h then
return (h(op)) -- call handler with the operand
elseif type(op) == "table" then
return #op -- primitive table length
else -- no handler available: error
error(···)
end
end
end
So print (#a_test); and print(getmetatable(a_test).__len(a_test)); should result into the same, isn't it?
By the way, why is the above excerpt from the Reference Manual refers to metatable(op) while it should be getmetatable(op)? At least I've tried print(metatable(a_test).__len(a_test));, and it ends into an error.
Answer
As Nneonneo noticed, this is an issue with the Lua version in use. Lua 5.2 seems to be required for the above to work.
From http://lua-users.org/wiki/LuaFaq:
Why doesn't the __gc and __len metamethods work on tables?
__len on tables is scheduled to be supported in 5.2. See LuaFiveTwo.
Since you're using 5.1, __len on tables does not work. Indeed, running your code on Lua 5.2 produces
1
1
as expected.
I'm learning Lua from a book, which is a bit old.
I've tried searching the web, but because of the use of the # sign in my search I get really confusing results.
It says that in order to use upvalue you need to use the % sign.
But when I write it in my code I get an error.
Account.new = function (starting_balance)
local self = {}
local balance = starting_balance
self.withdraw = function (v)
%balance = %balance - v;
end
return self
end
error is : unexpected symbol near '%'
Is there a new way to handle upvalues in Lua 5.x ?
Since Lua 5.0, there is no more such thing as a "upvalue sign". An upvalue is a local to the environment a function is declared in, and as such can simply be accessed as any other local variable.
In your case: just use balance instead of %balance.
From Lua 5.1, % is used as modulo operator.
A good but slightly outdated book is the online available version of Programming in Lua, and of course, the reference manual.
Must be a very old book!
The % as upvalue notation was removed in Lua 5.0. (Released 2003)
Since 5.0, Lua has lexical scoping;
that is, upvalues are automatic:
do
local balance = 0
function deposit ( v )
balance = balance + v
return balance
end
end
print ( deposit ( 5 ) )
Output:
5
I'd go with the closure http://www.lua.org/pil/6.1.html#closures