I’ll start the post by pointing out that my use of the word meme will follow relatively closely the original definition provided by Dawkins (hate him, love him, or find him a prat that has sometimes good ideas) in The Selfish Gene rather than the more modern usage of “standard image template with similar text on it.”
The reason is that I really need that definition to describe what I see happening often in code: the copy-pasting of snippets, or concepts, across projects, and projects, and projects, mutating slightly in some cases because of coding style rules and preferences.
This is particularly true when you’re dealing with frameworks, such as Rails and Autotools; the obvious reason for that is that most people will strive for consistency with someone else — if they try themselves, they might make a mistake, but someone else already did the work for them, so why not use the same code? Or a very slightly different one just to suit their tastes.
Generally speaking, consistency is a good thing. For instance if I can be guaranteed that a given piece of code will always follow the same structure throughout a codebase I can make it easier on me to mutate the code base if, as an example, a function call loses one of its parameters. But when you’re maintaining a (semi-)public framework, you no longer have control over the whole codebase, and that’s where the trouble starts.
As you no longer have control over your users, bad code memes are going to ruin your day for years: the moment when one influential user finds a way to work around a bug implement a nice trick, their meme will live on for years, and breaking it is going to be just painful. This is why Autotools-based build systems suck in many cases: they all copied old bad memes from another build system and they stuck around. Okay, there is a separate issue of people deciding to break all memes and creating something that barely works and will break at the first change in autoconf or automake, but that’s beside my current point.
So when people started adding
AC_CANONICAL_TARGET the result was an uphill battle to get people to drop it. It’s not like it’s a big problem for it to be there, it just makes the build system bloated, and it’s one of a thousand cuts that make Autotools so despised. I’m using this as an example, but there are plenty of other memes in autotools that are worse, breaking compatibility, or cross-compilation, or the maintainers only know what.
This is not an easy corner to get out of, adding warnings about the use of deprecated features can help, but sometimes it’s not as simple, because it’s not a feature being used, it’s the structure being the problem, which you can’t easily (or at all) warn on. So what do you do?
If your framework is internal to an organisation, a company or a project, your best option is to make sure that there are no pieces of code hanging around that uses the wrong paradigm. It’s easy to say “here is the best practices piece of code, follow that, not the bad examples” — but people don’t work that way, they will be looking on a search engine (or grep) for what they need done, and find the myriad bad examples to follow instead.
When your framework is open to the public and is used by people all around the world, well, there isn’t much you can do about it, beside being proactive and pointing out the bad examples and provide solutions to them that people can reference. This was the reason why I started Autotools Mythbuster, especially as a series of blog posts.
You could start breaking the bad code, but it would probably be a bad move for PR, given that people will complain loudly that your software is broken (see the multiple API breakages in libav/ffmpeg). Even if you were able to provide patches to all the broken software out there, it’s extremely unlikely that it’ll be seen as a good move, and it might make things worse if there is no clear backward compatibility with the new code, as then you’ll end up with the bad code and the good code wrapped around compatibility checks.
I don’t have a clean solution, unfortunately. My approach is fix and document, but it’s not always possible and it takes much more time than most people have to spare. It’s sad, but it’s the nature of software source code.