So, why Corona SDK insists on using dot instead of slash for require()?

Yes, I do know that Lua doc says it’s ANSI-C and has no concept of folder, and it uses dot instead of slash in the doc.

But, Lua require() does accept slash, it translate dot into slash internally, it’s simply not true to claim Lua language enforces dot notation for require().

I found previous thread claiming some device require dot notation to work, which doesn’t make sense to me, Lua is ANSI-C, it’s supposed to work cross-platform.

Worse still, only require() in Corona SDK follow this rule, anything else, eg. pathForFile(), you can and must use slash.

Corona SDK is only Lua-framework I know that does this, so really, for curiosity sake, why? 

It’s really not the only Lua framework that does this; it’s a Lua thing. Using dots, Lua will always pick the appropriate separator for you. So there’s no downside to using it.

Also, it’s not only require. Composer framework uses dots too.

But yes, there are inconsistencies when using subfolders within lfs and the system directories - I presume, because it’d have to work that bit harder to work out what you’re actually referring to when you are including file extensions.

e.g.

Is “player.sprites.left.bmp” a file called “left.bmp” in the directory “player/sprites”? or…?

This is actually the standard behavior of the Lua require() function.

As in, Corona Labs didn’t make it work this way; the Lua implementors did.

I believe they do this for portability reasons so that you don’t have to worry about which path separator to use (ie: ‘’ or ‘/’).

The Java #import statement uses dots ‘.’ for the path separators as well… but you never use dots in your Java File classes when specifying a path.  My point being that Lua is not the only language to do this.

the build process effectively “flattens” the folder structure of your source into a single archive (resource.car).  so what may have originally been “subfolder\file.lua” is literally named “subfolder.file.lu” inside the archive at resource root.

otoh, if you run the plain-vanilla command-line lua interpreter, then any of these should work equivalently:

a = require(“subfolder\file”)

b = require(“subfolder/file”)

c = require(“subfolder.file”)

Thx Dave for laying it out in code, I think many users didn’t realize this: plain-old lua does support slash, and doesn’t force anyone into using dot as path separator.

It’s might be slightly late to call for some changes on this, but here are my issues with current Corona SDK (latest release):

1)  It should update its warning message : “Lua requires package names to use ‘.’ as path separators, not ‘/’. Replace the ‘/’ characters with ‘.’ and try again.”

Because it’s not true, I understand Corona SDK want people to use dot as path separator, but this statement is misleading.

2)  It requires users to distinguish lua path from asset path.

Say I have some map data and map assets, I need to remember that map data (a lua table) is using dot and doesn’t need pathForFile, but map assets (image files) are using slash and need pathForFile.

3)  It should teach users about how lua path works in the doc , instead of enforcing one syntax.

I personally find using slash (/) easier because now all my paths are slash-based, but some people might prefer a different approach, power to them! Corona SDK could use a small section in its Lua guide to help users choose and avoid issues.

I do believe either approach will create some path problems, so there are no optimal solutions, but at least we are given the power to deal with those problems we face.

@bitnn, I think your complaint is really towards the Lua language maintainers, not Corona Labs.

As I’ve said before, this is a built-in Lua behavior.  Get used to it and move on.

Just like how the Java #import statement use dot notation instead of slashes.  (Perhaps inspiring Lua to do it this way as well.)

Either you don’t understand my statement, or you ignore just about everything I said.

And you ignore Dave’s reply as well.

If that’s how you would like to support Corona SDK, lock this thread.

I do understand what you’re saying, but my point is that the require() function’s dot ‘.’ handling is in the official open source Lua library code.  That’s the standard behavior.  The Corona SDK complies with this standard behavior.

Case-in-point, look at how the 3rd party LunaMark Lua library works.  This is a simple collection of Lua files organized into subdirectories.  It too uses dot notation in the require() function to access Lua files in subdirectories in both its examples and implementation, because this is the expected standard behavior.  My point being is that this is a non-Corona based Lua library accessing Lua files under subdirectories in a way that other Lua developers expect it to; using dots in-place of the directory separators.

   http://jgm.github.io/lunamark/doc/lunamark.writer.html

   https://github.com/jgm/lunamark/tree/master/lunamark

So, what you’re asking for is Corona to extend/modify the Lua language so that the require() function will accept ‘/’ and ‘\’ separators too.  I understand your reasoning, but this would be non-standard behavior where you would develop habits that would not be transferable to non-Corona based Lua applications.

@bitinn, sorry, but you’re the one being ignorant here. Joshua has already said that Lua is not the only language to reference libraries this way. He’s also not the only one to point out that it is a namespace issue, NOT a filename issue.

I understand that you are drawing a direct line from the filename location in the folder structure to the name of the Lua module being loaded by the require statement, but the fact is that you are NOT loading a “file” by using require.

What you are doing is asking the compiler to make a component library of the binary available to the current module in memory. This is done by addressing it by it’s namespace attribute. In Java, the namespace is arbitrarily defined but will typically - if always - be descriptive of the location of the file in the folder structure. In C#, the namespace is very often descriptive of the file location in the folder structure, but not always. In smalltalk, it is absolutely always - to my recollection (it’s been a while.)

The point I’m making is that the namespace is one thing and the location of the file is another. In Lua, the namespace is explicitly derived from the location of the file relative to the main.lua file and you cannot change this. It is NOT a Corona thing, it IS a Lua thing - for simplicity.

So, as Joshua said, get used to it and move on. It really is not something to be concerned about because you can’t change it and it is actually a good element of the language and definitely not something bad about Corona.

If you *really* want to know the nitty gritty details, then have a look at Lua’s source code in the link below.  Particularly it’s findfile() function which is used by the Lua require() function.

   http://www.lua.org/source/5.1/loadlib.c.html

From there, you can see that Lua does a substring substitution, replacing all dots “.” with the platform’s path separator.  For your quick reference, it looks like this in C…

name = luaL\_gsub(L, name, ".", LUA\_DIRSEP);

The idea being that Lua uses the dot ‘.’  to handle path separators in a cross-platform manner.  And also note that this is a very simplistic solution.  It merely does a character substitution.  So, if your require() string happened to not contain any dots and used platform specific slashes instead, then Lua would blindly accept it as-is (without modification) and attempt to load the file with the given string.  While this can work fine on the platform you’re targeting, it is not considered portable by the Lua language implementers.

And like @horacebury said, Lua’s dot notation emulates a namespace/packagename convention that Lua developers are already used to using with Lua modules/tables.  I believe that’s why they chose the dot ‘.’ as the portable separator.  Java does the same thing with its #import statements where the referenced Java file is expected to match 1-to-1 with its directory location, but with dot notation.

In any case, I think it’s good that you brought this up.  It may help those who are unaware that using dot notation is the standard means of accessing files from subdirectories.  :slight_smile:

it’s not a big deal to use dots in require(). I understand that it gets confusing when you are loading spritesheets that have both Lua module and a spritesheet image.

The best solution in my opinion is to make a little custom Lua function that will take care of both Lua module and spritesheet image based on a single filename string. Like

getSpriteSheet(‘path/with/slashes.png’).

Inside such function you can modify the passed string - drop the extension, replace slashes with dots and pass this modified path to require().

and along Lerg’s suggestion, you could also replace require() with one that has similar functionality (just remember to keep a reference to the original one!)

Programming in Lua (aka “PiL”) is a very worthwhile read (especially if you’d rather avoid the C source).  Chapter 15, and in particular 15.5 in this context, spells out in quite a lot of detail what require() does, and interacts with package.path, and just about everything else covered here so far.  Get 2nd edition though, as it best conforms for the 5.1.5 that Corona uses.

truth is, Lua doesn’t know squat about paths, nor does it care.  if you want to use slashes, and your OS likes it, then it’ll work just fine and Lua won’t even know.  everything that “just works” re filenames is because the OS managed to handle it “well”.  lua really/truly/honestly doesn’t know anything about your OS’s filesystem except what you’ve hardcoded into it.

fe, you even have to hardcode the separators into lua_conf at build-time to get the dot-substitution to do something reasonable, cuz Lua has no idea what the proper separator is.  (note that the dot-substitution ONLY happens on the module NAME, not on package.path which must contain literal OS separators – require() takes a module NAME as argument not a module path)

try building Lua for VMS (DEC VAX) - you can shove all sorts of nonsense characters into require (dollars, colons, brackets, semicolons, literal unsubstituted periods) as required by the OS to specify full paths, and it still all “just works” if what eventually makes it to the OS is a valid path.  (yes, i’ve done it; yes, i’m old :D)

BUT… in an embedded environment, every one of which is unique, you are to some extent at the mercy of the embedded environment.  Corona probably has a custom loader in package.loaders to handle pulling the compiled source out of the resource archive.  (i say “probably”, cuz i’ve never actually checked their implementation, just assume that’s how they’d do it, tho they could have “gone deeper”, replacing require() and/or loadfile() directly, though doubt they had to)

so, if the embedded environment says something to the effect of “we persist the dot-substitution notation into our resource archive prior to substitution” then there’s really not much you can do about it (except write “wrappers” around it, as per Lerg), and i’d guess that that’s where the “just get over it” sentiment comes from, cuz it’s a big fight otherwise.

hth

Thx all for your replies, special thx to Joshua, Dave and Lerg for the explanations and suggestions.

I understand the reason for dot-notation, however I haven’t run into an exotic OS system where slash-notation from working directory (or resource root), isn’t working as expected, so I am curious about which OS causes Corona SDK to disallow use of slash in require() outright.

I really think the warning message should be: " Hey we want you to use dot notation because that’s how Lua prefer to do namespace normalization and see this link for explanation" instead of " Lua requires package names to use ‘.’ as path separators, not ‘/’. Replace the ‘/’ characters with ‘.’ and try again."

Hope my making sense here.

Well, it is very clearly stated in the documentation and no other language does it differently, so I’m not sure why you would want that.

Are we going back to the “Lua doesn’t support slash as namespace” again? :slight_smile:

The fact is I can use slash as namespace in other Lua game engine just fine (they didn’t customize Lua language), and Corona warning message claims this is a “Lua design decision” is misleading.

  • TRUE, Lua would prefer you use dot so it can do normalization for you.

  • ALSO TRUE: But dot notation is not required, and so far slash notation haven’t failed me yet.

Anyway, I got what I needed to know. So I am going to leave this to Google to help future users.

It’s really not the only Lua framework that does this; it’s a Lua thing. Using dots, Lua will always pick the appropriate separator for you. So there’s no downside to using it.

Also, it’s not only require. Composer framework uses dots too.

But yes, there are inconsistencies when using subfolders within lfs and the system directories - I presume, because it’d have to work that bit harder to work out what you’re actually referring to when you are including file extensions.

e.g.

Is “player.sprites.left.bmp” a file called “left.bmp” in the directory “player/sprites”? or…?

This is actually the standard behavior of the Lua require() function.

As in, Corona Labs didn’t make it work this way; the Lua implementors did.

I believe they do this for portability reasons so that you don’t have to worry about which path separator to use (ie: ‘’ or ‘/’).

The Java #import statement uses dots ‘.’ for the path separators as well… but you never use dots in your Java File classes when specifying a path.  My point being that Lua is not the only language to do this.

the build process effectively “flattens” the folder structure of your source into a single archive (resource.car).  so what may have originally been “subfolder\file.lua” is literally named “subfolder.file.lu” inside the archive at resource root.

otoh, if you run the plain-vanilla command-line lua interpreter, then any of these should work equivalently:

a = require(“subfolder\file”)

b = require(“subfolder/file”)

c = require(“subfolder.file”)

Thx Dave for laying it out in code, I think many users didn’t realize this: plain-old lua does support slash, and doesn’t force anyone into using dot as path separator.

It’s might be slightly late to call for some changes on this, but here are my issues with current Corona SDK (latest release):

1)  It should update its warning message : “Lua requires package names to use ‘.’ as path separators, not ‘/’. Replace the ‘/’ characters with ‘.’ and try again.”

Because it’s not true, I understand Corona SDK want people to use dot as path separator, but this statement is misleading.

2)  It requires users to distinguish lua path from asset path.

Say I have some map data and map assets, I need to remember that map data (a lua table) is using dot and doesn’t need pathForFile, but map assets (image files) are using slash and need pathForFile.

3)  It should teach users about how lua path works in the doc , instead of enforcing one syntax.

I personally find using slash (/) easier because now all my paths are slash-based, but some people might prefer a different approach, power to them! Corona SDK could use a small section in its Lua guide to help users choose and avoid issues.

I do believe either approach will create some path problems, so there are no optimal solutions, but at least we are given the power to deal with those problems we face.

@bitnn, I think your complaint is really towards the Lua language maintainers, not Corona Labs.

As I’ve said before, this is a built-in Lua behavior.  Get used to it and move on.

Just like how the Java #import statement use dot notation instead of slashes.  (Perhaps inspiring Lua to do it this way as well.)