Why Lua's builtin REPL cannot access previously delcared local vars? - lua

See the following example:
$ lua
Lua 5.4.4 Copyright (C) 1994-2022 Lua.org, PUC-Rio
> local a = 123
> print(a)
nil
This works as expected:
> local a = 123; print(a)
123
How should I understand the behavior compared to the doc?
The scope of a local variable begins at the first statement after its declaration and lasts until the last non-void statement of the innermost block that includes the declaration.

In the Lua REPL, each (multi)line is loaded as an independent chunk via luaL_loadbuffer. The same system that makes require("mod_a") independent of require("mod_b").
Therefore, the quoted sentence still applies because every time the REPL prints a > (compared to a >> which denotes a multiline) a new block starts, thereby passing the boundary of "the last non-void statement of the innermost block".

Lua REPL treats each line of code as a separate chunk (as if it was a separate Lua file).
When a chunk execution is finished, all its local variables are lost.
So, only global variables are preserved between lines.
Lua REPL is just a REPL, it is not a debugger, where you would be able to watch and modify all variables while program is running.
To use local variables in a multi-line program in Lua REPL: start with do, enter multiple commands, and finally enter end to execute the program you entered.
$ lua
Lua 5.4.3 Copyright (C) 1994-2021 Lua.org, PUC-Rio
> do
>> local a = 123
>> print(a)
>> end
123
>

Related

Lua io.write() adds unwanted material to output string

When I start an interactive Lua shell, io.write() adds unwanted material after the string I want it to print. print(), however does not:
[user#manjaro lua]$ lua
Lua 5.4.2 Copyright (C) 1994-2020 Lua.org, PUC-Rio
> io.write('hello world')
hello worldfile (0x7fcc979d4520)
> print('hello world')
hello world
And when I use io.write() in a program it works fine too:
--hello.lua
io.write('hello world\n')
print ('hello world')
Output:
[user#manjaro lua]$ lua hello.lua
hello world
hello world
I'm using Manjaro Linux on a Dell desktop. Can anyone tell me what's going on here? Thanks in advance.
EDIT: I should add, perhaps, that the unwanted material is always something like this:
file (0x7f346234d520)
It's always 'file' followed by what looks like a large hexadecimal number in parentheses. The exact number stays constant within one shell session but varies between different shell sessions.
"file (0x7fcc979d4520)" (or whatever address) is the return value of the io.write call, with an implicit tostring.
The lua(1) man page says
In interactive mode, lua prompts the user, reads lines from the standard input, and executes them as they are read. If the line contains an expression or list of expressions, then the line is evaluated and the results are printed.
The trouble here is that io.write('hello world') could be either an expression or a statement. Since it's a valid expression, the interpreter outputs that unwanted return value.
As a workaround, try adding a semicolon:
> io.write('hello world\n');
hello world
Although Lua usually doesn't require a semicolon for each statement if it's at the end of a line, it does allow it. And important here, it means the syntax can't be an expression, only a statement which calls the function. So the interpreter won't output the returned value.
You are just seeing the return value of io.write when you call io.write manually, interactively. When using the Lua, uh, shell, if you want to call it that, it almost always prints the return value of any function(s) you call.
file(blabblah) is the internal representation of the file you are writing to (probably just a hex memory address, but who knows?)

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

Input to Lua? Just like a console?

I'm trying to make a scripting tutorial for a friend (I'm not too good at it myself but okay) and I'm trying to make it so the input creates an actual line of code that does what they typed. EG:
Input: print("hello")
hello
I understand this is what a console does, but is there any way I can do it with Lua?
Thanks.
just run the lua command to get a lua "REPL":
$ ./lua
Lua 5.3.1 Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print("hello")
hello
>
load
load (ld [, source [, mode [, env]]])
Loads a chunk.
If ld is a string, the chunk is this string.
...
If there are no syntactic errors, returns the compiled chunk as a function; otherwise, returns nil plus the error message.
local input = [[
local args = {...}
print(args[1], args[3]) -- 42 1
return args[1] + args[2], args[2] + args[3]
]]
print(load(input)(42, 99, 1)) -- 141 100
As you can see, the input has access to globals, you can pass values into his code and get the returns.
One way to do this would be using the loadstring function.
Example:
run = loadstring("print('Hello World!'")
run()
Output:
Hello World!

What is the expected behaviour of io.stdin:seek()?

In Lua documentation, calling :seek() on a file object is supposed to return how much data has been read through the file. However, when I call this method on stdin it does not return consistent numbers.
When I open terminal and run the Lua REPL and execute io.stdin:seek() I get random numbers. In one tab I might get:
Lua 5.2.0 Copyright (C) 1994-2011 Lua.org, PUC-Rio
> =io.stdin:seek()
2091
In another tab I could get instead:
Lua 5.2.0 Copyright (C) 1994-2011 Lua.org, PUC-Rio
> =io.stdin:seek()
486
What explains this behaviour whereby calling seek() on stdin returns a number that seems to have no relevance to how much input Lua has received?
And how else might I be able to retrieve how much data has been read through stdin?

lua - dofile, how fill stdin from lua?

http://www.lua.org/manual/5.1/manual.html#pdf-dofile tells
dofile ([filename])
Opens the named file and executes its contents as a Lua chunk. When called without arguments, dofile executes the contents of the standard input (stdin). Returns all values returned by the chunk. In case of errors, dofile propagates the error to its caller (that is, dofile does not run in protected mode).
How fill stdin from lua for case when called without arguments?
If you're running a lua script or the lua interpreter in interactive mode from a command shell, calling dofile() will just get input from stdin. You'll see a blinking cursor in the shell where you can enter the lua code you want to run.
Note, running dofile in this fashion is a blocking calling, which means execution flow in your script or the lua interpreter will pause until it reads eof. Usually this means you have to enter Ctrl + Z under windows or Ctrl + D under *nix bash shell at the end.
This is an example:
-bash-4.0$ ./lua
Lua 5.3.0 (alpha) Copyright (C) 1994-2014 Lua.org, PUC-Rio
> dofile()
a = 3; print(a)
3
>
After inputting a = 3; print(a), I pressed Ctrl + D, which represents EOF on Unix. dofile() loads the input and executes it.

Resources