lua-users home
lua-l archive

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


> 2013/4/15 Brian Kelley <brian.kelley@gmail.com>:
>
>     It's getting to be politically correct in the Lua community
>     to regard globals as bad.
>
> The attitude (the term 'prejudice' almost sneaked out, but I bit it back)
> is illustrated most clearly by the pejorative term "polluting the global
> namespace".

I have said that sentence more than once, and I think it is one of
the most important things to care about if we want a thriving Lua
ecosystem.

> You can tell the programs written by the supporters of this ideology.
> They start out something like this:
>
>     local pairs, ipairs, print, tostring, getmetatable, setmetatable
>         = pairs, ipairs, print, tostring, getmetatable, setmetatable
>
> There are also plenty of forward declarations of local functions.

This idiom (redeclaring the standard library functions locally) does
not have much to do with the issue of global namespace pollution.

When we say "don't pollute the global namespace" we mean something
else, see below.

> Now, I don't want to knock this style of programming altogether. I've used
> it myself. But to preach that is the One Correct Way is going too far.
> If one is using Lua via the interactive interpreter (which I do a lot)
> it is intensely annoying to cut-and-paste code written this way. Those
> locals last only for the chunk in which they are defined, and the
> interactive interpreter bites off the smallest chunks possible. I keep
> forgetting to make extra `do`..`end` blocks all the time.

I agree, but this is a technical problem of the interpreter.

So what do we (or at least I) mean by "don't pollute the global namespace"?
We mean that you should not create globals in *library code*.

Why is that? Imagine that your program depends on library A which uses
global foo. Now *you* use global foo, and library A stops working.

Now you can say "don't do that, check which globals libraries are using".
OK. Now let's say you depend on library A and library B. Library B also
uses global foo. There is no way library B author could have known you
would use it with library A.

Even worse: library B depends on library C which uses global foo...

These issues are not imaginary, they are real, they happen when you make
large scale programs. I am not even talking about modules that abuse the
fact that some modules expose globals to monkey-patch them and do it
wrong: https://gist.github.com/catwell/3803669

I have not written require "socket.unix" to discover this bug, I have written
require "redis", because redis-lua required socket.unix (it has been patched
since then).

So if you use Redis you cannot use TCP sockets anymore. This is the kind of
thing that should not happen. I don't care what you do within your own
codebase, but libraries should not break other code when required.

-- 
Pierre Chapuis