
コピー&ペーストプログラミング(単にペーストと呼ばれることもある)とは、コピー&ペースト操作によって生成される、非常に反復的なコンピュータプログラミングコードの作成のことです。これは主に軽蔑的な用語であり、この用語を使用する人は、プログラミング能力や抽象化を作成する能力が不足していることを暗に示唆していることが多いです。また、サブルーチンやライブラリが通常使用されるにもかかわらず、技術的な制約(表現力の不十分な開発環境など)の結果である場合もあります。しかし、定型文、ループ展開(コンパイラが自動的にサポートしていない場合)、メタプログラミング機能が限られている言語、特定のプログラミングイディオムなど、コピー&ペーストプログラミングが許容または必要となる場合もあり、一部のソースコードエディタではスニペットの形でサポートされています。
コピー&ペーストによるプログラミングは、経験の浅いプログラマーや学生プログラマーがよく行う手法で、彼らはゼロからコードを書くことを困難または煩わしいと感じ、自分の問題解決の基礎として使える既成のソリューションや部分的なソリューションを探すことを好む。[ 1 ] (カーゴカルトプログラミング も参照)
経験の浅いプログラマーがコードをコピーする場合、多くの場合、コピー元のコードを完全に理解していません。そのため、問題はコピー&ペーストという行為そのものよりも、むしろプログラミングにおける経験不足と勇気の欠如に起因しています。コードは、友人や同僚のコード、インターネットフォーラム、オープンソースプロジェクト、教授やティーチングアシスタントから提供されたコード、コンピュータサイエンスの教科書など、さまざまなソースから入手されることがよくあります。結果として、スタイルがバラバラになり、新たな解決策がもはや必要のない問題に取り組むための不要なコードが含まれるリスクがあります。
さらに問題なのは、個別のソースコードで行われた仮定や設計上の選択が、新しい環境に移された際にはもはや適用されなくなるため、バグが容易に混入する可能性があることです。
また、このようなコードは、意図せず難読化される可能性もある。なぜなら、変数、クラス、関数などの名前は通常変更されずに残されるが、新しいコンテキストではそれらの目的が全く異なる場合があるからである。[ 1 ]
コピー&ペーストによるプログラミングは、ループ構造、関数、サブルーチンなど、コンピュータ言語に共通する機能に対する理解不足が原因である場合もある。

コピー&ペーストは、経験豊富なプログラマーによっても行われ、彼らは多くの場合、十分にテストされ、すぐに使用できるコードスニペットや汎用アルゴリズムの独自のライブラリを持っており、特定のタスクに簡単に適応させることができます。[ 2 ]
コードの重複の一種であるコピー&ペーストによるプログラミングには、いくつかの本質的な問題があります。ソースコードとコピーされたコードの間に意味的な関連性が保持されていない場合、これらの問題はさらに深刻化します。この場合、変更が必要になった際に、重複箇所をすべて探し出すのに時間が浪費されます。(元のコードやコピーされたコードに適切なコメントが付けられていれば、この問題は部分的に軽減できますが、それでも同じ編集を何度も行うという問題は残ります。また、コード保守ではコメントの更新が省略されることが多いため、[ 3 ]遠隔地のコード箇所を示すコメントは、古くなってしまうことで悪名高いです。)
オブジェクト指向手法の支持者は、コピー&ペーストによる「コードライブラリ」の使用にも反対しています。汎用アルゴリズムの複数の変更されたコピーを作成する代わりに、オブジェクト指向アプローチでは、アルゴリズムを再利用可能なカプセル化されたクラスに抽象化します。クラスは、継承とオーバーロードを完全にサポートして柔軟に記述されるため、すべての呼び出しコードは、元のコードを変更するのではなく、この汎用コードを直接使用するようにインターフェースできます。[ 4 ]追加の機能が必要になると、ライブラリは拡張されます(後方互換性を維持しながら)。このようにして、元のアルゴリズムに修正すべきバグがある場合や改善できる場合、それを使用するすべてのソフトウェアが恩恵を受けることができます。汎用プログラミングは、抽象化を作成するための追加のツールを提供します。
コードの分岐は、大規模チームによるソフトウェア開発において一般的な手法であり、両方のブランチで並行開発が可能になるため、開発サイクルを短縮できます。従来の分岐には、次のような特徴があります。
コピー&ペーストは、従来のブランチングよりも形式ばらない代替手段であり、既存製品から新製品が派生する場合など、ブランチが時間の経過とともにますます分岐していくことが予想される場合によく使用されます。
新製品を開発する手段として、コピー&ペーストによるプログラミングにはいくつかの利点があります。なぜなら、新しい開発プロジェクトでは既存製品のコードに手を加えないからです。
デメリットは以下のとおりです。
上記と同様に、コピー&ペースト方式の代替案としては、モジュール化された方式が考えられます。

最も有害なコピー&ペーストプログラミングの形態の一つは、反復的なタスクを実行するコード、または何らかの変数に応じて同じ基本タスクのバリエーションを実行するコードに見られます。各インスタンスは、上記からコピーされ、わずかな変更を加えて再度貼り付けられます。有害な影響には、次のようなものがあります。
コピー&ペーストによるプログラミングは、有効なプログラミング手法として時折認められています。これは、クラス宣言や標準ライブラリのインポートといった定型的なコード、あるいは既存のコードテンプレート(内容が空であったり、スタブ関数が含まれていたりするもの)をフレームワークとして使用し、そこにコードを書き込む場合によく見られます。
プログラミングの慣用表現やデザインパターンは、定型的なコードを使用するという点で、コピー&ペーストプログラミングに似ています。場合によっては、これをコードスニペットとして表現し、必要なときに貼り付けることができますが、多くの場合、プログラマーの頭の中から単に思い出すだけで済みます。また、慣用表現をコードテンプレートに還元できない場合もあります。しかし、ほとんどの場合、慣用表現をコードに還元できたとしても、関数として抽象化されるほど長くなるか、直接入力できるほど短くなるかのどちらかになります。
Subtextプログラミング言語は、コピー&ペーストを「非犯罪化」することを目的とした研究プロジェクトです。この言語では、コピー&ペーストが主要なインタラクションモデルとなるため、アンチパターンとはみなされません。
簡単な例としては、for ループがあり、これは次のように表現できます。for(inti=0;i!=n;++i){}
このようなforループを使用したサンプルコードは次のようになります。
void foo ( int n ) { for ( int i = 0 ; i != n ; ++ i ) { /* 本体 */ } }ループ処理のコードは、以下のコードスニペット(型と変数名を指定)によって生成された可能性があります。
for ( $type $loop_var = 0 ; $loop_var != $stop ; ++ $loop_var ) { /* 本体 */ }