I'm playing with Lua following this link: https://www.lua.org/pil/4.2.html and get confused about a point.
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> x=10
> local i=1
> while i<=x do
>> local x = i*2
>> print(x)
>> i=i+1
>> end
stdin:1: attempt to compare nil with number
stack traceback:
stdin:1: in main chunk
[C]: in ?
I guess this error message indicates that something is wrong with the expression while i<=x. Any comments are greatly appreciated.
EDIT: I just realize that it's probably because it does not work in a terminal.
It did not work out in an interactive terminal. Because local i=1 is understood by terminal as a chunk by itself once you hit enter. That is why the "attempt to compare nil with number" error; because i is not defined, i.e., nil in this case. To correct it, put the first two lines and the while loop inside of a do chuck as the following.
> do
>> x = 10
>> local i=1
>> while i<=x do
>> local x = i*2
>> print(x)
>> i = i+1
>> end
>> end
2
4
6
8
10
12
14
16
18
20
>
Actually the problem is in local i=1 try
> local i = 1
> print(i)
The problem is that when running the console, it seems that the line is a chunk and the variable is local inside that chunk.
you can fix that by using a global variable or you can do this
> local i = 1 do
>> print(i)
>> end
Which results in chunk structure like this [local i [print(i)]] therefore i can be accessed. Note also that local x = i*2 is valid since it is inside the while - do chunk.
Your code would also work correctly, if it was inside a Lua file.
I could reproduce the problem in Lua 5.3.4 as well.
If you read on in the Lua docs, chapter 4.2 – Local Variables and Blocks, you'll get to the sentence
Beware that this example will not work as expected if you enter it in interactive mode. The second line, local i = 1, is a complete chunk by itself.
This addresses exactly the issue in question. So it seems that the Lua interpreter has limited support for an outmost chunk (that is clearly present in a Lua file). But this behaviour seems to me acceptable and understandable in view of the compactness of language and interpreter.
So, when in interactive mode,
either leave out the local before variable i to make it work:
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>x=10
Lua>i=1
Lua>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end
or start enclose the whole by a block:
Lua 5.3.4 Copyright (C) 1994-2017 Lua.org, PUC-Rio
Lua>do
...>local x=10
...>local i=1
...>while i<=x do
...>local x=i*2
...>print(x)
...>i=i+1
...>end
...>end
Both options will produce to the regular (and expected) output:
2
4
6
8
10
12
14
16
18
20
Related
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 playing with Lua, following the link: https://www.lua.org/pil/8.html. And I got confused a bit...
> i = 100
> local i=3
> f=loadstring("i=i+1")
> print(i)
100
> g=function() i=i+1 end
> print(i)
100
> f()
> print(i)
101
> g()
> print(i)
102
I mean, why neither f nor g use the local i?
You already have an answer for that in one of your previous questions.
> local i=3
Since you are using Lua interpreter in interactive mode, the local i is only visible in the chunk I have quoted above. Hence, both f and g increase global i as they don't see local i from the chunk quoted.
Consider writing your Lua code to a file and then executing them via e.g.: lua file.lua.
first of all, this is my first time coding in Lua, let alone coding at all.
I'm testing out lua for making some mods, and I can't really figure out what i'm doing wrong. I'm trying to get my script to say 2 different things with 2 different values, but lua keeps printing BOTH values.
Here is my code:
sword = unequipped
if sword == equipped then
print("This feels quite heavy")end
if sword == unequipped then
print("I feel unstoppable")
end
When I run the script, it prints out both values, so in terminal, it says;
This feels quite heavy
I feel unstoppable
How can i fix this?
Thanks in advance!
I suspect your problem is you haven't defined unequipped or equipped so they are both nil so sword is equal to both of them.
In general when you have a problem like this, try using the interactive interpreter. e.g.
bash-3.2$ lua
Lua 5.2.4 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> sword = unequipped
> print(sword)
nil
> print(equipped)
nil
> print(sword == equipped)
true
I know that there's tonumber() function, but the problem is that i need to convert larger numbers like 1000100110100011111010101001001001001100100101 . I can write that by myself, but is there a way to integrate that in function? And if I write that in current function, it returns different number. For example: through wolfram alpha, I converted "Something" (base 36) to binary and got 10010011001100011001011110001100000110110101100.
If I put that in my custom function and convert back to base 36, I get 1Z141Z3 or 4294967295 (range for unassigned int)
In Lua 5.3, tonumber works just fine:
Lua 5.3.2 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> tonumber("1000100110100011111010101001001001001100100101",2)
37834277032741
> tonumber("10010011001100011001011110001100000110110101100",2)
80920602611116
Lua supports 64bit integers since 5.3. Is your Lua up to date?
Open http://www.lua.org/cgi-bin/demo
and execute this quick and dirty conversion. The result matches your quoted Wolfram Alpha number.
local dec = 80920602611116
local bin = "10010011001100011001011110001100000110110101100"
bin = string.reverse(bin)
local sum = 0
for i = 1, string.len(bin) do
num = string.sub(bin, i,i) == "1" and 1 or 0
sum = sum + num * math.pow(2, i-1)
end
print(sum)
How Can I tell if line number x in a Lua script will respond to the Lua line hook?
Example:
1 first = 1
2
3 function test ( data )
4 if first == 0 then
5 print ("\r\n")
6 end
7 print(data)
8 --[[
9 first = 0
10 ]]
11 end
12
13 test()
14
Line 2,6,8,9,10,12 and 14 does not call a line hook. After I have loaded and executed the script, can I some how, from C/C++, get a table of the executable line numbers?
lua_getinfo can return a table of valid lines if you include L in what.
Some code sample:
local exec_lines = {}
local function exec_line_counter(event, line)
table.insert(exec_lines, line)$
end
local function count_exec_lines(lua_file)
local external_chunk = loadfile(lua_file)
debug.sethook(exec_line_counter, "l")
external_chunk()
debug.sethook()
-- Removing `debug.sethook()` lines:
table.remove(exec_lines, 1)
table.remove(exec_lines, #exec_lines)
end
count_exec_lines("test.lua")
Output of:
table.sort(exec_lines)
for i, num in ipairs(exec_lines) do
print(num)
end
is
1
3
4
7
11
11 <--- not sure why this duplicates. Lack of return? Or because following tailcall?
13
NOTE: it would log only lines being parsed. In Your test case, it does not cover 5th and 6th line, because first not being 0.
Another way of doing this and solving noted case - just simply parsing Lua source: counting and skipping lines which consists only of Lua comments:
--lines
--[[ blocks ]]
EDIT: ah, shoot, edited Your question of doing this with C/C++. Hooking functions can be done with plain C API too. Might make an example if You didn't get a basic idea from an my answer already made :)