[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: require() relative to calling file
- From: Ross Berteig <ross@...>
- Date: Fri, 3 Feb 2017 14:52:41 -0800
On 2/3/2017 1:14 PM, Sean Conner wrote:
It was thus said that the Great Russell Haley once stated:
On Fri, Feb 3, 2017 at 1:16 AM, Scott Morgan <firstname.lastname@example.org> wrote:
On 02/03/2017 07:34 AM, Russell Haley wrote:
But the question was what is the argument against the approach
described. It always has seemed to me that Lua goes to great length
to search relative paths and entirely negates to look in the
application path for no reason whatsoever. It was one of the most
confusing things when I first started looking at Lua.
Lua does use the EXE path in Windows, but under *nix systems things
aren't so simple. There's no guarantee that the path to the executable
exists and no clear way to determine it even if it does (some hacky,
platform dependant ways, but nothing clean).
For scripts I plan to drop somewhere on $PATH and use as a general tool,
I usually use the handy pl.app function require_here() from Penlight.
That and the handy pl.lapp module seem to be part of nearly any tool I
write that is expected to be used as anything other than a one-off
solution to a problem.
require_here() operates by assuming that it is invoked from a Lua script
that itself was executable. On Unix-like systems, it would begin with
"#!/usr/bin/env lua" or similar. On Windows, I simply bind *.lua files
to my preferred lua.exe using the assoc and ftype commands in the usual
On Windows, the result is that arg[-1] names lua.exe, arg has a fully
qualified path to the script file, and the rest of arg .. arg[#arg]
is the usual command line arguments.
On *nix, the details will depend on the processing of #! lines, and
potentially on the behavior of /usr/bin/env if that is included. While
the full story of #! is rich with history and quirky details, in modern
systems the behavior is pretty stable. In practice, the interpreter is
invoked with a fully qualified name of the script. I can't find a
promise to that effect, but testing on an older Ubuntu and an Amazon
Linux instance is consistent. See  for the full history, and a nice
table of what to expect to happen tested on a range of *nix platforms.
For testing, I have /usr/bin/lua as the system's Lua 5.1.4, but later
versions should behave the same. Two files in ~/bin act as probes, and
are both the same trivial Lua script differing only in the shebang
lines, and marked executable. ~/bin is in $PATH.
$ cat bin/tpath
print(arg[-1], arg, arg)
$ tpath hi
/usr/bin/lua /home/ross/bin/tpath hi
$ cat bin/tepath
print(arg[-1], arg, arg)
$ tepath hi
lua /home/ross/bin/tpath hi
Aside from the name of my home directory, the output on the AWS EC2
instance running Amazon Linux was identical. I don't happen to have a
true Unix system at hand, but the chart at the link above tends to imply
that OpenBSD, NetBSD and FreeBSD will get the same answer.
So it certainly is true that in general a process on Unix cannot depend
on argv to contain a fully qualified path. But it appears that the
shebang interpreter invocation is special and provides a fully qualified
name of the script. And that allows modules to be stored next to the
script that needs them.
Ross Berteig Ross@CheshireEng.com
Cheshire Engineering Corp. http://www.CheshireEng.com/
+1 626 303 1602