lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

On Oct 23, 2011, at 12:36 PM, Sam Roberts wrote:

> On Sun, Oct 23, 2011 at 1:03 AM, Mark Hamburg <> wrote:
>>> 4. It adds the module to the global namespace. This, in my opinion, is a bad thing because it creates hidden dependencies -- i.e., code can use a module that it never required simply because some other code required it earlier and it became available in the global namespace.
>> The problem here is that if module "foo" does a require "bar" which does a require "baz" and then module "foo" does a require "bleen", then bleen can see bar and baz without ever requiring them:
>>        foo
>>                require "bar"
>>                        require "baz"
>>                require "bleen"
>>                        -- bar and baz are now visible to bleen
> This is a way to create bugs, but I can't see it as a very big
> problem. There are way better ways to code difficult and perplexing
> bugs, in any language.
> What happens is someone removes the require baz, the next time the
> code runs, something in bleen errors out, with a message about trying
> to index global baz. You look at the code, it does indeed use the baz
> module, but didn't require it. Bad coder, no cookie! You then put the
> require into the module definition.
> How often can a bug like this actually suck significant
> trouble-shooting time? Compared to the time to type require"logging"
> into the top of every lua file in your code base?
> I actually started using a lint tool for python, because it doesn't
> have a way to make libs like logging globally available across an
> entire app, you have to import it everywhere you use it. (actually, it
> probably does have a way to do this, but would involve doing things to
> the core that would be frowned upon by pythonistas everywhere)
> I got tired of integration tests failing because I'd put calls to
> logging.debug() in some code, and forget to add the import, so for the
> first time ever with a dynamic language, I found a lint tool and
> started using it. I feel its a failing in python that I'd not like lua
> to repeat. And its sucked valuable time from me, our integration tests
> take a long time to run and get back to us with a "you forgot to
> import logging, try again" message.
> And its worth noting that this can only happen to people who don't
> unit test, any unit test like
> -- bleen-test
>  require"bleen"
>  bleen.do_something()
> would fail if blaz or any other dependency of bleen hadn't been
> required by bleen.

It isn't all that hard to fix, but on a multi-person project it's annoying when you have to go fix someone else's code (and more annoying if then leads to a debate over whether or not their code was broken to begin with though maybe that's a sign about the engineers...). I think it also gets particularly fuzzy on hierarchical namespaces where if a name is missing from a namespace you have to ask whether it isn't there because it was never supposed to be there or whether it isn't there because you didn't do an extra require.

>>> 5. It mucks with the environment to make it "easy" to export functions. But then to compensate for this, it offers package.seeall which results in a module that reveals a lot of globals in its table which have nothing to do with the module -- i.e., it pollutes the API for the module.
>> Bascially, the issues here has to do with whether it bothers one that if module foo uses the module function with package.seeall then references such as foo.print and foo.pairs and foo.math.sin are all valid.
> Its odd, even ugly, but its also invisible if you do for k,v in
> pairs(a_mod) do print(k,v) end. You have to
> be pretty perverse to go looking for these things, and start to use
> instead of io. Most people would never even know about this
> side effect if they didn't think about it deeply, or hear somebody
> else bring it up.

True, you have to go looking, but think also about the sandboxing case. Is it safe to re-export a particular module into a carefully constructed sandbox environment? What if that module without changing it's API starts using package.seeall in its implementation?