command-line -l option issue

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

command-line -l option issue

Tony Papadimitriou
The command-line –l option help says: -l name  require library 'name'
 
I assumed this to be equivalent to starting a script with: require ‘name’
 
Now, if I have a library file named xxx.lua which also includes a function named xxx,
using the –l method vs the explicit require method does not behave the same.
 
To reproduce:
 
File xxx.lua contains just this: function xxx() print 'hello' end
 
And, here’s the output I get for each case:
 
c:\temp>lua -l xxx -e "xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
stack traceback:
        (command line):1: in main chunk
        [C]: in ?
 
c:\temp>lua -e "require 'xxx' xxx()
hello
 
Is this expected behavior, or bug? If expected, then perhaps the help message is a bit misleading.
 
Thank you.
 
Reply | Threaded
Open this post in threaded view
|

Re: command-line -l option issue

Vadim A. Misbakh-Soloviov
It is not a bug. Just `-l` executes after `-e`. That's all. It is same for all
Lua versions including LuaJIT.

Reply | Threaded
Open this post in threaded view
|

Re: command-line -l option issue

Tony Papadimitriou
But in that case, shouldn't it be that xxx is nil rather than boolean?
 
c:\temp>lua -l xxx -e "xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
 
as in:
 
c:\temp>lua -e "xxx()
lua: (command line):1: attempt to call a nil value (global 'xxx')
 
 
-----Original Message-----
From: Vadim A. Misbakh-Soloviov
Sent: Saturday, February 25, 2017 11:17 PM
To: Lua mailing list
Subject: Re: command-line -l option issue
 
It is not a bug. Just `-l` executes after `-e`. That's all. It is same for
all
Lua versions including LuaJIT.
Reply | Threaded
Open this post in threaded view
|

Re: command-line -l option issue

Tony Papadimitriou
More on this.  I think the function name being the same as the library filename is the problem.  Because if I change xxx() to zzz(), no problem.
 
Let xxx.lua contain this:
 
function xxx() print 'hello' end
function zzz() print 'hello' end
 
then:
 
c:\temp>lua -l xxx -e xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
stack traceback:
        (command line):1: in main chunk
        [C]: in ?
 
c:\temp>lua -l xxx -e zzz()
hello
 
which indicates –l is processed before –e but something else is causing this.
 
Sent: Sunday, February 26, 2017 12:31 AM
Subject: Re: command-line -l option issue
 
But in that case, shouldn't it be that xxx is nil rather than boolean?
 
c:\temp>lua -l xxx -e "xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
 
as in:
 
c:\temp>lua -e "xxx()
lua: (command line):1: attempt to call a nil value (global 'xxx')
 
 
-----Original Message-----
From: Vadim A. Misbakh-Soloviov
Sent: Saturday, February 25, 2017 11:17 PM
To: Lua mailing list
Subject: Re: command-line -l option issue
 
It is not a bug. Just `-l` executes after `-e`. That's all. It is same for
all
Lua versions including LuaJIT.
Reply | Threaded
Open this post in threaded view
|

Re: command-line -l option issue

Tony Papadimitriou-2
And, apparently, Lua v5.1 does it correctly.  Lua 5.2 and 5.3 do it wrong.
 
Sent: Sunday, February 26, 2017 12:41 AM
Subject: Re: command-line -l option issue
 
More on this.  I think the function name being the same as the library filename is the problem.  Because if I change xxx() to zzz(), no problem.
 
Let xxx.lua contain this:
 
function xxx() print 'hello' end
function zzz() print 'hello' end
 
then:
 
c:\temp>lua -l xxx -e xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
stack traceback:
        (command line):1: in main chunk
        [C]: in ?
 
c:\temp>lua -l xxx -e zzz()
hello
 
which indicates –l is processed before –e but something else is causing this.
 
Sent: Sunday, February 26, 2017 12:31 AM
Subject: Re: command-line -l option issue
 
But in that case, shouldn't it be that xxx is nil rather than boolean?
 
c:\temp>lua -l xxx -e "xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
 
as in:
 
c:\temp>lua -e "xxx()
lua: (command line):1: attempt to call a nil value (global 'xxx')
 
 
-----Original Message-----
From: Vadim A. Misbakh-Soloviov
Sent: Saturday, February 25, 2017 11:17 PM
To: Lua mailing list
Subject: Re: command-line -l option issue
 
It is not a bug. Just `-l` executes after `-e`. That's all. It is same for
all
Lua versions including LuaJIT.
Reply | Threaded
Open this post in threaded view
|

Re: command-line -l option issue

Jonathan Goble
In reply to this post by Tony Papadimitriou
On Sat, Feb 25, 2017 at 3:31 PM Tony Papadimitriou <[hidden email]> wrote:
The command-line –l option help says: -l name  require library 'name'
 
I assumed this to be equivalent to starting a script with: require ‘name’
 
Now, if I have a library file named xxx.lua which also includes a function named xxx,
using the –l method vs the explicit require method does not behave the same.
 
To reproduce:
 
File xxx.lua contains just this: function xxx() print 'hello' end
 
And, here’s the output I get for each case:
 
c:\temp>lua -l xxx -e "xxx()
lua: (command line):1: attempt to call a boolean value (global 'xxx')
stack traceback:
        (command line):1: in main chunk
        [C]: in ?
 
c:\temp>lua -e "require 'xxx' xxx()
hello
 
Is this expected behavior, or bug? If expected, then perhaps the help message is a bit misleading.
 
Thank you.

`-l name` is not equivalent to `require "name"`. It is equivalent to `name = require "name"`. This is important because require() always returns a value. This value is either the value returned by the module chunk, or if that returns nothing, the value of package.loaded["name"]. If the module does not modify that field or explicitly return a value, then that field is set to true before require returns, so require will return true in that case.

So what happens here is that Lua finds xxx.lua and runs it, which defines the global `xxx` variable as a function. However, xxx.lua neither returns a value nor modifies package.loaded["xxx"], so that field is set to true, and the call to require "xxx" then returns true, which is then assigned to the global `xxx`, overwriting the function that was there. All of this behavior of require() is expected and documented behavior [1], and this is why you get "attempt to call a boolean value".

The fact that `-l xxx` is equal to `xxx = require "xxx"` rather than merely `require "xxx"` is not clear from reading the reference manual, but it, and the change in behavior from 5.1 to 5.2, make sense when you consider standard Luaisms and the history of Lua. In 5.1, the standard way of writing a module used the module() function [2], which directly injected the module contents into a specified global variable, so there was no need to capture a return value, and the behavior of `-l` assumed this. In 5.2, module() was removed as part of the general changes to environments, and the standard way of writing modules, especially modules aiming to be cross-compatible with 5.1 and 5.2, shifted to explicitly returning the module table, so the behavior of `-l` changed to adapt to this.

P.S. Please don't use Comic Sans. Really. It's not appropriate for serious discussions, and drives me crazy when it is used that way. [3]