[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: Re: require() relative to calling file
- From: Russell Haley <russ.haley@...>
- Date: Fri, 3 Feb 2017 22:48:41 -0800
On Fri, Feb 3, 2017 at 4:28 PM, Sean Conner <firstname.lastname@example.org> wrote:
> It was thus said that the Great Russell Haley once stated:
>> On Fri, Feb 3, 2017 at 1:14 PM, Sean Conner <email@example.com> wrote:
>> > But this is something *UNIX* does not provide "out of the box."
>> But if the arg contains path denoting characters (/,\), why not
>> parse out the path and add it to the search path for require? Then
>> both scenarios are intrinsically covered with *very little* overhead.
>> It's done once when the calling script is executed.
> The argument is over who is responsible for doing so? The Lua stand alone
> interpreter? The Lua library that's embedded in a C application? The
> application written in Lua?
> I would put it with the application written in Lua, but that's me.
>> > Unix has no concept of an "application path".
>> Are we talking about Unix or Lua? I would argue Unix and "Lua on Unix"
>> and even C assumes that the current path is the "application path",
>> which is why all these system searches the current path in various
>> system functions. In Lua, it searches the current path for require
>> modules even if the script is in a different directory! Also, what
>> would you think if "ls" only searched the current path when you
>> specified a path in your search string?
> Lua searches the current path because the default Lua path (and cpath)
> contain './?.lua' as one of the components. And unless './' is part of
> $PATH, a Unix shell *WON'T* execute a program in the current directory:
> [spc]lucy:/tmp>touch foo
> [spc]lucy:/tmp>chmod 755 foo
> -bash: foo: command not found
> I would have to add "./" to my path to execute a command in the current
> [spc]lucy:/tmp>export PATH=./:$PATH
> If executing a program in the current directory works, it's because "./"
> was added to $PATH (and $LUA_PATH and $LUA_CPATH) at some point; it's far
> from a default.
> Unix has a "current working directory" concept. It does not have an
> "application directory" concept. Windows does (and the two can be different
> when a program runs).
>> >And neither does C for that
>> > matter. Remember, Lua uses the standard C library  and the C standard
>> > library makes no mention of paths (or directories for that matter).
>> Sure, you are correct. But as you pointed out, Lua is portable to
>> non-Unix systems that do not have path concepts, but it DOES use paths
>> in systems that support it.
> Not really. All it does is apply some textual transformations to a
> filename before ultimately calling fopen() (the C call). If some
> hypothetical system out there used '#' as a path seperator, then Lua would
> still be able to load files in a relative manner. It just that instead of
> package path being:
> it would be:
> To Lua, these are just opaque strings used to create potential filenames.
>> So, as I said, why not parse arg for
>> appropriate path delimiters and use them when provided? "Because it's
>> hard" does not seem like a very good reason. Moreover, as you pointed
>> out parsing arg for delimiters is not what would be consider a
>> difficult task (albeit C has surprised me before! ha ha).
> Again, I think the argument is about where this happens.
>> I think it would be much better to say:
>> On all platforms that support file systems, Lua will:
>> 1) Search the current directory
> Lua does this already.
>> 2) Search the path of the executing script when it differs from the
>> current path (i.e. the user has specified extra path information)
> Not all systems that have file systems support directories. Granted,
> they're not in popular use, but they do exist. And given the relunctance of
> the Lua team to support C99 (dispite being 18 years old) I don't see them
> adding this any time soon. I could be wrong though.
>> 3) Package.path and package.cpath (which has environment variables
>> appended if I understand correctly)
>> I could see it getting more complicated if a relative path was
>> specified, but environment variables can have relative paths too.
>> This next comment is not about you, Sean, but a general comment about
>> arguments made in Lua's defense: I think it's funny how on one side
>> some people argue that Lua is not C and not bound by it's constraints
>> and design guidelines,
> Yes, and I'm one of those.
>> but on the other side the argument is made that
>> Lua uses standard C so is intrinsically tied to C idiosyncrasies? I
>> would categorize this as an arbitrary use of ISO C limitations for
>> covering a "not in my Unix" argument.
> And I argue that as well. It's just that to ensure maximum portability,
> you have to realize that Lua is built upon C89 only. You want to interate
> through entries in a directory? Well, the code for that *IS* system
> dependent (Unix, Windows, AmigaOS, and VMS all have a different API for
> that). But once you have such code, there's no reason to tie it to a
> specific API---you can "Luaize" it (for lack of a better term). So, for
> for entry in dir("some/path/to/somewhere") do
> could work regardless of the underlying C API.
>> > So what *is* this trivial solution then?
>> Parse arg for path delimiters and include that path in the search
>> criteria for modules. Trivial...
> So add it to your Lua application. That way, you don't have to wait for
> the Lua team to add it.
I have counter arguments but that's not the point. The only reason I
spoke up is because I ran into this myself when I was starting with
Lua. The way it searches the current path and chooses the defaults to
search is opaque to casual users. The simple fact is Lua searches a
number of places for a variety of things to help the user out but
negates this simple yet effective addition that won't break any other
operating environment because you won't be using path separators if
there is no filesystem. It provides huge functionality, doesn't break
anything, provides continuity between that "other small operating
system" that Lua supports, is 100% backwards compatible (because
nobody could do it before) and is as simple as saving the results of a
one time tokenization (is that the right word?). The best answer to
"why not?" is "because that's not the way we did it before". Fair
enough, but I agree with the OP that it's a puzzling omission. And
this is coming from a guy who likes to start counting from 1.