What's frustrating is that DRY is often paired with something like "The Rule of Three". Do repeat yourself about three times until you actually understand what it is that's being repeated (or whether it's just coincidental) so it can be refactored. But a lot of people forget that part and focus only on DRY.
Is the magic number 1024 the same in all instances, for example. Or is it merely a coincidence that it's the same in a few places. Is the apparently repetitious code:
In several places really the same? Or is it a coincidence that right now none of them pass any parameters to create_context and use the same params in their call to action?
Avoiding the repetition makes it hard to even ask that question. And disentangling the different cases later is riskier than keeping a few pieces of repeated code around for a while to understand the situation better.
> The DRY principle is stated as "Every piece of knowledge must have a single, unambiguous, authoritative representation within a system".
I don't avoid copy-pasting as a rule, but would deduplicate a block of code if they represent different occurrences of the same "knowledge" of a shared procedure, but create separate functions or duplicate code if each one encodes "knowledge" of a different process to be followed. Of course it's hard to define and codify "knowledge" in an objective form that different people can use the same way, but in my experience, I still feel this rule (and the rest of my gut feeling for refactoring) hasn't provided bad guidance in the situations I've encountered so far (though it's not always applicable, takes domain understanding and experience to identify "knowledge", and it's sometimes difficult nonetheless).
I like this formulation, because it calls you to answer the question of whether several snippets of repeated code represent the same knowledge or different knowledge.
GP's example of the constant "1024" present in multiple places doesn't necessarily mean they represent the same knowledge; one could be a bit mask, another could be the default number of items to show on a page, and another could be a buffer size. DRY-ing these different pieces of knowledge could be disastrous if the requirements for one of the uses changes. New requirement: only display 10 items on a page. Good luck with your bit mask reading the second and fourth bits now and filling your 10-byte buffer 100 times more often. New requirement: We added more flags, the bit mask is now 0x80000000. Good luck serving pages with 2 billion items and your memory usage randomly spiking by 2GB.
Instead of calling it 'The Rule of Three', call it WET (Write Everything Twice); makes it easier to remember (although I think that is one less repetition than suggested in the parent.)
Nobody should always DRY or WET; my context is I wrote some code for a greenfield part of a project and was told to DRY multiple times. Was easy to reply 'I prefer WET here' and link to an article on WET rather than explaining the redundancy.
Interestingly, I just looked at the wikipedia page for DRY (https://en.wikipedia.org/wiki/Don%27t_repeat_yourself) and see they also mention another acronym - AHA (avoid hasty abstractions); I might use that in the future.
The name is largely irrelevant, though WET may be more memorable when attached to DRY. The important element is the deliberate introduction or allowance of repetition with the intent (and ideally actually doing) of examining and refactoring later. Later is often not even that much later, IME. Usually the next step I take after putting in the repetition because I can see the common structure properly while it's all fresh in my head, but I couldn't see it when I initially started writing it (or saw the wrong part as the common structure, which bit me enough that I committed to the rule of three idea).
Every few months there is a comment complaining about DRY, and a counter comment complaining about misunderstanding of DRY. So allow me:
DRY originated from The Pragmatic Programmer, and is not about avoiding duplicated code. In fact, quite a bit of duplicated code doesn't break the DRY rule as originally defined.
If I make my own list, I'll be sure to put "Understand what DRY is before complaining about it." :-)
Same here, furthermore I've written so much crazy code early on to avoid breaking The Rule, looking back I'm double horrified; at what I did, and knowing that a lot of junior programmers are going through that phase now.
Glad to see DRY called out here. I've seen so much crazy code simply to avoid breaking, The Rule.