lua-users home
lua-l archive

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


I know I'll be burned at the stake but here it goes:

Monkey Patching is Never Really Needed. People do it just because they can, and when they can't people just find other solutions and move on -- if it was possible to monkeypatch number addition so that 1+1=10, there would certainly be people defending it as a useful use-case ("my application only deals with binary numbers!")

Monkey patching is a source of problems and non-reusable code, and promotes breakage of encapsulation and API contracts.

Enrique's example in Rule #3 is to me a perfect argument against monkey patching, actually: nowhere in the _interface_ for the multiplication function it says that it is _implemented_ in terms of addition. If the sum function wasn't local, the monkey patching trick works, but then you upgrade summult to a new version where multiplication was internally optimized, and your client code breaks.

There are always better solutions; the mechanisms that allow monkey patching are there for low-level metaprogramming, not for regular module/application development.

Anticipating the usual "but my module is private! I'll deal with my mess" response, which Steve graciously let pass as an exemption:

> Of course, this all applies to code that is meant to be used by other people ;)

All is fine with private code with monkey patching tricks until:

(a) the day it grows to the point that it's useful enough that you would benefit from having it released as a public module but you can't because it doesn't play well with others, or

(b) the day you have to integrate it within your organization with those from coworkers (note that Steve said "used by other people", which does not necessarily mean releasing publicly), and you start having within your private ecosystem all the issues of a monkeypatchful world.

All of course in my opinion; feel free  to disagree.

Hisham (rant over too)

On Apr 16, 2014 6:39 AM, "steve donovan" <steve.j.donovan@gmail.com> wrote:
>
> On Mon, Apr 14, 2014 at 12:06 PM, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> > Rule #3: Allow monkeypatching
> >    Agree 5%. No monkeypatching should be the default, and
> >    it should be documented clearly when a module allows it.
>
> There are a lot of good reasons for not patching Lua libraries, and
> very few good reasons why one should. Quick (and temporary) fixing for
> broken third-party libs is one of those good reasons.
>
> If a person takes a dislike to table.insert[1] (and it's one of the
> easiest functions to dislike, because it's really two functions in
> one) then surely that person just defines a new function to do exactly
> what they want?  Why confuse the known and documented contract of  an
> existing standard library function?
>
> And they may put it into 'table', this is a lesser evil and only
> really applies to defining modules meant to be consumed by other
> people's code.  (stdlib used to do this a lot and fortunately Gary has
> now made this optional)
>
> As for routinely tweaking third-party modules, the same consideration
> holds, since in a large system any global changes can have unintended
> effects.  That post I mentioned about why monkey-patching is bad for
> Ruby gets the issue right:  there are all these Rails plugins which
> tweak the environment in incompatible ways, and - wait for it -
> there's usually a perfectly good solution[2] that doesn't need such
> radical surgery.
>
> The reason for this rant: it is impossible to do big reliable projects
> when people have this idea that they can patch things to suit
> themselves.  It's not the mechanism that bothers me, it's the policy;
> the meme that patching is good engineering practice.
>
> Perhaps there is some confusion between modules - stateless
> collections of functions - and classes, where _instances_ have state?
> Inheriting from a class creates a new class and one can do what one
> likes[3]  So at the least, make a copy of something that needs to be
> patched, so that the patch doesn't propagate and mess with other vital
> machinery.
>

>
> steve d. (rant over)
>
> [1] My favourite local assign is "local append = table.insert" for
> purposes of appending at the end. It's possible to accidentally
> trigger weird behaviour, but in practice I haven't seen this as a
> problem worth getting excited about.
> [2] http://devblog.avdi.org/2008/02/23/why-monkeypatching-is-destroying-ruby/
> [3] modulo "fragile base class" problem.  Inheritance isn't so cool
> anymore, which is fortunate because the Lua community cannot agree on
> how to implement it.
>