Page 2 of 2

Re: cross version compatible module definition

Posted: Sun Apr 19, 2015 4:01 pm
by undef
bartbes wrote:Because 5.10 is a later version than 5.2?
Ok, I kinda assumed you were talking about a version that already existed, so I just misread 5.10 as 5.1.0.

Re: cross version compatible module definition

Posted: Sun Apr 19, 2015 8:55 pm
by kikito
Inny wrote:The search form didn't answer my question so I'll start a thread about it, and I'm guessing Kikito is the one I'd like to answer it
Howdy, I will do my best.
Inny wrote:The feature in particular I'm after is simulating _ENV's safety. I think this it the way to go:

Code: Select all

local module = function(_ENV)
  __ = {}

   ...
  return __
end

local environment = setmetatable({}, {__index = _G})
if setfenv then setfenv(module, environment) end
return module(environment)
What makes you think that code is any better than just setting and returning the module table? Why do you think you need to manipulate the module's environment at all?
nobody wrote:
Inny wrote:Is checking for setfenv enough to discover 5.1?
No. Quite a few people define setfenv / getfenv as compatibility functions [...] If you need to check the version, check _VERSION !
I strongly disagree with both parts of this assessment.

First, I think testing for the existence of setfenv is just enough. If someone has a non-standard definition of setfenv, there are two possible scenarios: that their own setfenv is compatible with the standard one (maybe doing something extra on the side, like printing in a log), or that it doesn't (i.e. they have redefined it to be an empty function). In the first case, your code will work just fine if you just test for setfenv. In the second case, your code will never work. Even if you use _VERSION, and detect that you are in 5.1, when you try to use setfenv it will do nothing anyway.

On the other hand, I don't think that using the _VERSION string is a good idea. The browser world has told us again and again that it is not a good idea to check a string to deduce capabilities (at least if you want your code to be usable in the long run and you want to keep your sanity). Instead you would check for capabilities directly. That means doing if setfenv then ... or if type(setfenv)=='function' then ... if you want.

But the best option is not having the problem in the first place. I still don't know why you think you need to manipulate the module's environment in the first place, Inny.

Re: cross version compatible module definition

Posted: Sun Apr 19, 2015 9:30 pm
by Inny
Why do you think you need to manipulate the module's environment at all?
I mostly don't. Like for ascii.lua, there's nothing to sandbox. For the thing that I used as example for this thread, funky.lua, it's superfluous as I doubt I'd hit the 200 upvalues limit anywhere. So for right now, It just be nice to have an environment that's not _G, which I can apply strict.lua to and catch programming errors. Longer term, I may have a non-programmer writing code for me. That needs minimal sandboxing. Thus I guess the point of this thread was me asking what's just enough to catch rogue global vars and nothing more.

I do agree however, that well written modules shouldn't even need this or even think about it, so if anyone asked me what I recommend as a module definition, I answer with "return local module", and not python's file-implicit environments.

Re: cross version compatible module definition

Posted: Sun Apr 19, 2015 9:49 pm
by kikito
Inny wrote:Thus I guess the point of this thread was me asking what's just enough to catch rogue global vars and nothing more.
For that, I recommend Luacheck. Run it on every source file you want and it will warn you about implicit globals and a bunch of other stuff.

Re: cross version compatible module definition

Posted: Mon Apr 20, 2015 11:52 pm
by Inny
kikito wrote:For that, I recommend Luacheck. Run it on every source file you want and it will warn you about implicit globals and a bunch of other stuff.
Awesome advice, thank you.