lua-users home
lua-l archive

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


It was thus said that the Great Enrique Garcia Cota once stated:

That made me chuckle :)

 you cannot reason about monkeypatched code!

I respectfully disagree. You cannot reason about _badly monkeypatched code_, just like you can't reason about badly written code. But it's the "badly" part that is a problem.

Monkeypatching is a tool. It's a bit more error-prone than others, but mostly because it has been around (popularly) less time. There are things that can be done only through it. That alone justifies its existence in my opinion. But also requires strong reminders of the  dangers of not using it correctly. 

Your comment has made me re-read my article. Despite the title being "allow" and the initial warning In some passages it does certainly sound like I am _encouraging_ the use of monkeypatching. I'll edit the article to remove that  tone, and will try to add more warnings.

Thanks a lot for your feedback!

Enrique (kikito / @otikik)


On Mon, Apr 14, 2014 at 11:55 AM, Sean Conner <sean@conman.org> wrote:
It was thus said that the Great Enrique Garcia Cota once stated:
> Hi there,
>
> I've written a series of articles about building Lua modules - it's here:
>
> http://kiki.to/blog/2014/03/30/a-guide-to-building-lua-modules/
>
> I would appreciate any feedback or comments on it.
>
> Thanks and best regards,

  Of all the articles listed, the one I had the most problem with was
article #3: Allow monkeypatching, which covers two different topics,
monkeypatching and locals.

  This is bad advice.  The purpose of locals is not necessarily a speed
optimization (although it is to a very small degree) but a way of consistent
behavior and not unduely modifying the global namespace (the major reason
for Lua's 5.2 change of how modules are loaded) *nor* the module namespace.

  In Lua 5.1, once you call module(), you loose the existing global
namespace, and because of that, you need to cache any existing modules you
use into local variables.  For Lua 5.2 you can do this (which I recommend),
but it is not mandatory [1][2].

  As for monkeypatching, yes, you can do it.  But it's not that common in
the Lua community (thank God!) and for good reason: you cannot reason about
monkeypatched code!  Sure, you might have a Good Reason to patch some
function, but like the long discussion about __index [3] showed, it can lead
to surprising results if you change the semantics of functions underneath
the functions that call the monkeypatched functions, and by "surprising
results" I mean "impossible to find bugs at 3:00 am on a major holiday" [2].

  And the example you give for monkeypatching, overriding the function
sum(), is a very bad one, because you are breaking the basic assumptions of
arthmetic.  Again, you are free to do that, but if I'm using a module you
wrote and I found that it changed the underlying semantics of a function I'm
using, I'll delete the module (and probably any other modules you wrote, as
I can no longer trust them).

  Again, it can't be said enough:  it's hard enough to debug code.  There's
no reason to make it harder.

  -spc (Did a proof-of-concept of monkeypatching a live executable---and
        felt horribly icky afterwards ... )

[1]     In http://lua-users.org/wiki/ModulesTutorial there is code to inject
        the global environment as a backup for the module environment.  This
        I do not like as well.  One, because you can get to the global
        environment by mistake [2], and two, because of monkeypatching.

[2]     It's hard enough to debug code.  There's no reason to make it
        harder.

[3]     Start here: http://lua-users.org/lists/lua-l/2014-04/msg00517.html