Monkeypatching For Humans

Although I love strings, sometimes the String class can break your heart. For example, in C#, there is no String.Left() function. Fair enough; we can roll up our sleeves and write our own function lickety-split:


This is a companion discussion topic for the original blog entry at: http://www.codinghorror.com/blog/2008/07/monkeypatching-for-humans.html

Or how about:

public static string Left(string s, int len)
{
return s.Substring(0, len);
}

Perl has this option of overriding methods for years.
(either on other object, or a built-in function)
and generally, it’s not miss-used.
As said, it’s a cultural this. This ability is marked in bold letters saying if you really know what you are doing, and anyone how don’t know, just don’t do.

Monkey patching

Is that what the cool kids are calling it these days?

What exactly is your problem with php? Must you continuously suck at the Microsoft teat?

So… what should we reply to the sheeple who like to parrot the following:

In C, you can shoot yourself in the foot.
In C++, you can blow your whole leg off.

How about:

In Ruby, you can not only blow yourself up but take your entire team with you!

You missed Groovy in your list of Dynamic languages. http://groovy.codehaus.org/ It works seamlessly back and forth with Existing Java code.

I like Groovy’s approach. It uses the methodMissing API to dynamically add methods to specific classes, so that if you wanted to implement String#left() you would simply write:
String.metaClass.left = { len -
if (len == 0 || s.Length == 0)
return ;
else if (s.Length = len)
return s;
else
return s.Substring(0, len);
}

then every single string would now have a left(int len) function on it :slight_smile:

For .net extension methods, the current recommendations are to put them in a separate namespace so that there aren’t any unexpected side-effects from other developers consuming your code (especially if you’re writing a library / framework). I certainly don’t want string.Left polluting my code just because I use some widget. But the widget writer is free to use any of that and I never have to see it.

Thinking back to C++, where there are a dozen different string implementations, it certainly is nice to just add 1 extension method that you need, rather than use / struggle around using an implementation that is missing that 1 method.

It’s another thing done mainly for Linq but retaining nice side benefits outside of using linq. Typesafe macros on steroids I guess, but it’s just syntactic sugar in the end. You’re not altering the class in any way, nor can you (easily/unknowningly) affect already-written code.

I have the same thoughts on Aspect Oriented Programming. All sorts of goop get unexpectedly injected into all sorts of places.

Sometime people just want clever toys rather than having to just hack out good code.

And as you point out; most code is junk. Good programmers will write good code that uses AOP or Monkeypatching; they will have good reasons, it will be well documented and it wont break. Conversely a poor programmer is going to write junk no matter what tool they use; at least using MP they wont whine about having to use old fashioned tools

It’s always great to see the scientists you link to… thanks.

It’s worth mentioning that monkeypatching is an incredibly valuable technique for writing unit tests.

For example, to test how your code-under-test behaves when it is unexpectedly unable to open a file, your tests should not have to go sniffing around the file system, deleting or changing permission on critical files. This obviously would have huge potential for unintended side-effects if your test fails to clean up properly after itself, and hence would be a very fiddly test to write.

Instead, your test should simply patch the file ‘open’ method, replacing it with ‘raisePlease()’, a small function of your own devising which simply raises an exception. Then when the code-under-test is called, it calls what it thinks is file.open(), but is actually raisePlease().

This makes it a fairly idiot-proof two line test. We use it literally every day. I can’t think of a single instance of a monkeypatch with global scope in our production (ie. not testing) code.

Hugs,

spot on Jeff…

InfoQ has a write up with an overview of solutions for scoping extensions (C# is one example):
http://www.infoq.com/articles/ruby-open-classes-monkeypatching

Prototype plays very nice with any other framework and has for some time. I’ve used it with YUI and jQuery. Several years ago (v. 1.4, I think) Prototype added some methods to Object.prototype at which point users rebelled and the author, Sam Stephenson, rightly removed it.

I love people. They’re wonderful.

Year after year us C++ programmers keep hearing that the ability to overload operators is the most awful crime against humanity ever committed.

Now it turns out that overloading operators is still evil, but somehow monkeypatching operators and methods and constructors and core language features is the most wonderful and exciting thing to ever be created in the entire universe.

Thanks a million, guys. I knew that C++ wasn’t as bad as you all made it out to be. :wink:

Also, I simply love the modern approach to language design: take C++, subtract the bits that are hard to explain in the teach yourself in 21 days book, add in some bytecode and a garbage collector, and then piece by piece add in all the bits you took out because it turns out they’re actually useful.

Well, ok, the everything and the kitchen sink approach where every string class seems to end up with a hundred thousand manipulation methods and regular expression processors and XML parsers and every type of string oepration shoved into the interface is funny, too.

C# and Java have the everything is an object thing, and the better development would be to make free non-member functions into first-class citizens, so that a string can be effectively an atomic little unit that does one thing and does it well (with a small and testable interface and no BFUD think of everything anyone will ever do with a sting) and all the manipulators can exist separately. Then when the internal implementation of string changes, it doesn’t beak all the monkeycrappers.

But that won’t happen - cos operator overloading is evil! It’s evil, I say! And therefore C# is perfect!

Total agree. In addition, using such extension will likely be nightmare for code review.

And remember, kids, ALWAYS MOUNT A SCRATCH MONKEY!

I had never heard of this, actually. Interesting.
http://edp.org/monkey.htm

It’s worth mentioning that monkeypatching is an incredibly valuable technique for writing unit tests.

Ah, you’re right – dynamically altering methods would be very useful for testing.

[criticisms of Left() code]

That code doesn’t actually exist; it’s only used as an example. I do agree with all the amendments / suggestions people have made, but critiquing dummy code is a little beside the point don’t you agree? :slight_smile:

This reminds me of the old arguments of the usefulness of multiple inheritance in C++. When I was managing a team of programmers we had the rule that if you wanted to use multiple inheritance in your design, you had to convince two other team members that it was the best design for your problem otherwise you had to do it another way.

It’s a useful solution for a very small set of problems.

Full-blown dynamic language monkeypatching goes even further; it might even be the ultimate expression of programming power. Is there anything more pure and godlike than programming your own programming language?

It’ll only truly be programming your own programming language if you’re able to extend the syntax of the language itself. Which reminds me of Lisp :slight_smile: and this: http://xkcd.com/224/

That code doesn’t actually exist; it’s only used as an example. I do agree with all the amendments / suggestions people have made, but critiquing dummy code is a little beside the point don’t you agree? :slight_smile:

Perhaps then you could mark it as such? I.e. being dummy code.

That code doesn’t actually exist; it’s only used as an example. I do agree with all the amendments / suggestions people have made, but critiquing dummy code is a little beside the point don’t you agree? :slight_smile:

Jeff, Jeff, Jeff.

Have we learned nothing from Stairway to Heaven, a/k/a FizzBuzz? if you write a blog post about Foo and include a few lines of dummy code, you can expect a widely distributed code review and programming contest to ensue.

Expecting otherwise is very much like opening your eyes in the morning and switching on the radio to hear if Global Peace has been declared while you sleep.

Laudable Optimism.

You only post this kind of stuff to scare me, don’t you?

Every 5 years or so we have a new batch of programmers, and many re-invent previously discovered and, often rightly, discarded concepts. The idea of extending core class definitions like this is not new and, one may note, not prevalent. Why? Imagine the amount of undocumented extensions soon to be written. Really, you don’t want the functionality to implicitly override existing core functions on top of that. Give us developers enough rope and we will hang both ourselves and everyone downstream of us …

A certain level of pre-defined, ensured, common functionality means we can pick up on new code bases quicker. If youwant this, use inheritance.

I view this right up there with Shuggoths – can you hear the voices on the wind? Tekka-li-li! (okay, that reference may be a bit obscure).
Flee the Mountains of Madness!