How to Copy and Paste

Imagine this challenge: not copying and pasting for a week. One week, without ctrl-V (or ctrl-Y, or just plain old p).

Yes, challenging, and it’ll make you realize just how much we’re violating the concept of reuse, copying pasting the same 1 or 2 or 200 lines of code. Yes, I recently saw a method that was obviously copied from the one just above it, another 200 line method, with — get this — only four lines changed, for two variables, one a boolean and the other a string.

So the first way to copying and pasting properly is to avoid doing it. (An interesting feature of an editor would be to monitor the copying and pasting a programmer does during a coding session, and warn them when the metric becomes excessive: “Another 38 lines copied … are you sure that shouldn’t be a method?”)

The next step is to copy as little as possible. *Never* more than two lines. (Forgiven is the boilerplate code some languages require, and the copyright comments at the top of files.)

My metric with regular coding is one line: if I start to copy two lines, I consider rewriting that as a method. (This is fun, when copy-and-paste is replaced by cut-and-paste, meaning that there is some refactoring and reuse afoot.)

Now this is the best part, and this little trick will avoid a lot of bugs that result from bad copying and pasting: don’t copy the characters that you’ll be replacing.

For example, we have the line of Java:

        Foo bar = new Foo(String.valueOf(args[0]), new Frobnitz(args[1], args[2]), 6, "six", "vi");

And there will be a similar variable, named “baz”, but initialized with args 3, 4, and 5, and with different numbers:

        Foo baz = new Foo(String.valueOf(args[3]), new Frobnitz(args[4], args[5]), 7, "seven", "vii");

The normal way to copy would be to copy the entire line, then go back and modify the newly-pasted code, replacing “bar” with “baz”, 0 with 3, 1 with 4, etc. The problem with that is that it is too easy (and thus common) to omit updating one of the variables, leading to this:

        Foo bar = new Foo(String.valueOf(args[0]), new Frobnitz(args[1], args[2]), 6, "six", "vi");
        Foo baz = new Foo(String.valueOf(args[3]), new Frobnitz(args[4], args[2]), 7, "seven", "vii");

Note that “args[2]” is wrong above, not being updated after the second line was pasted.

How to avoid this: only copy the code that will not be replaced. So in the above, we would first copy up to (but not including) the “0”, paste that, type “0”, then copy and paste the next string up through “args[“:

        Foo bar = new Foo(String.valueOf(args[
                                              0
                                               ]), new Frobnitz(args[

At that point, I’d just type the entire remainder of the line, since it’s faster (and more accurate) to type a few characters than to copy and paste them.

So the copy and paste rules, in summary:

  • Avoid it.
  • Keep it short.
  • Keep what you paste.
Advertisements