自動プログラミング:コードを書くコードを書く[終了]


105

The Pragmatic Programmerの本を読んだ後、私が最もおもしろいと思った議論の1つは、「コードを書くコードを書く」ことでした。

ネット上でそれ以上の説明や記事を探してみましたが、このテーマに関するいくつかの良い記事を見つけましたが、特定のコード実装や良い例はまだ見つかりませんでした。

それはまだあまり一般的な議論ではなく、ドキュメントが欠けているか、多くの人々に受け入れられていないように感じます。それについてもっと知りたいです。

このテーマについてどう思いますか?生産性を本当に向上させるものですか?本、ブログ、スライドショーなどのテーマに関する良いリソースは何ですか?


いくつかのコード例は、その実装をよりよく理解できるようにするために大いに評価されるでしょう。


メタプログラミング、生成的プログラミング、コード生成など、関連するさまざまなプログラミングテクニックに関するwikiページを次に示します


32
私はかつてコードを書いたコードを書いたコードを書いた... :)
Benjol

9
@ベンジョル:Lispで書いていたのですか?
コンプマン

11
さらに、サーバーサイド言語は、HTML、CSS、およびJavaScriptを生成することにより、これを常に実行します。より多くのhtmlを作成するjavascriptでhtmlを作成するサーバー側スクリプトを作成するサーバー側スクリプトを使用できますが、誰もそれがどれほど一般的であるかについて目をつぶることはありません。
zzzzBov

8
まだ行っていない場合は、IBM developerWorksの記事シリーズメタプログラミングの技術 第1 第2部、および第3 をご覧ください。
ジョントブラー

3
AtomWeaver(atomweaver.com)は自動プログラミングの好例です。まず、Luaで再利用可能なミニプログラムを作成します。次に、これらの資産を再利用してシステムをモデル化します。次に、AtomWeaverは、システムの最終ソースコードを生成するための「ミニジェネレーター」を含むLuaプログラムを作成します。その後、モデルを微調整して再生成できます。
ルイクラード

回答:


49

Lispの世界では、コードを書くコードを書くコードを見るのは非常に一般的です(など)。したがって、適切なサイズのLispまたはSchemeプロジェクトは、良いコード例として役立ちます。ラケットコンパイラとランタイムソース、およびBiglooを調べることをお勧めします。それらのライブラリは素晴らしいです。

生産性に関しては、ほとんどすべての開発作業でメタプログラミングを主要な手法として使用しており、コードサイズの削減と可読性の向上の両方に役立つことは明らかです。重要なのはドメイン固有言語を使用することであり、メタプログラミングはそれらを実装する最も効率的な方法の1つです。


67

私はもう少し進んで、コードを書くコードを書く代わりに、オブジェクト、メソッド、関数を生成するコードを書くことを好みます。これは、たとえばLispマクロまたはRubyの動的プログラム変更機能で実現できます。

わずかな違いは、自動的に生成されたソースファイルで終わらないことです。通常、これらのファイルは人間が読める形式ではないため、変更することはできません。制御できないものでコードベースを増やすという考えは好きではありません。

このテーマについて読んで楽しんだ本の1つは、Rubyのメタプログラミング(Ruby言語を知っている場合)です。


コメントの次の質問の後に編集します。

なぜ生成コードをコーディングしなければならないのに、なぜ有用なのでしょうか?ユーザー入力に応じてさまざまなものを生成できるコードを作成して、何度も何度も再利用できるようにする必要がありますか?

まず、メタプログラミングは目標ではなく、ツールです。「かっこいい」または「Xはすべての開発者が使用すべきだ」と言ったため、メタプログラミングを使用しないでください。

メタプログラミングを使用する正当な理由の1つは、コードで見つけた他の通常のプログラミングテクニック(継承、デザインパターンなど)が達成できない一般的なパターン(繰り返されるものとしてのパターン)を一般化することだと思います。

ヨルダンによって前記一つの典型的な使用例では、データベース処理とORM(オブジェクト関係マッピング)です。繰り返しますが、Rubyでは、ORMに適用されるメタプログラミングの優れた例であるActiveRecordを見る必要があります。

最後のメモとして:

「メタプログラミングを適用したいのですが、コードのどこに適用できますか?」とは思わないでください

考えてみて、「私はすべての私のコードの上に繰り返しています。このパターンを参照してください、私はより小さく、より再利用可能なものにコードをリファクタリングする方法を見つけることができません。多分私を助けることができるメタプログラミング?」


3
@Jose:最も一般的には、テンプレートを介してコードを生成します。たとえば、Apache(N-)velocityまたはVisual Studio T4テンプレートがあります。次に、メタデータをテンプレートにフィードし、それから新しいファイルを作成するプログラムを作成します。それは非常に簡単で、UIスケルトン、エンティティなどを生成するために常にやっています
ファルコン

2
@Jose Faeti、Lispマクロ(またはプラットフォームの設定に応じてClojure、またはNemerle)を詳しく見てください。
SKロジック

1
ポリシーや状態などのパターンを置き換えることができるメタプログラミングを追加しますが、ランタイムコストはかかりません。これは、一般的なリファクタリングでは達成できない問題だけでなく、より優れた代替手段でもあります。
-deadalnix

1
@Jose Faeti:Pythonを知っているようです。メタプログラミング機能もありますが、実際には使用していません。見てみましょうデンジャラス高度なPythonのPDFを
キット

3
@Falcon:コードを生成する最悪の方法であるIMO。組み込みのメタプログラミング機能のない言語の回避策は非常に貧弱です。JavaまたはC#を生成する代わりに、そのコードを高レベルのJVMまたは.NET言語で記述する方が適切です。
ケビンクライン

19

さらに良いことに、あなたのためにあなたのコードを書く他の誰かが書いたコードを使用してください。

コードの自動化は、一般にORMやその他のデータベースインタラクションコードに適しています。もちろん、繰り返しながらも同様のコードを構築するのに適しています。

もちろん、似たようなクラスをたくさん構築しているなら、おそらくもっと早く動的言語で同じことを達成できたかもしれませんが、私は脱線します。

これは多くの人に受け入れられていますが、多くの場合、ソフトウェアにはコードジェネレーターというラベルが付いています。

CodeSmithやMyGenerationなどの企業や製品を参照するか、次のウィキペディアの記事をご覧ください:http : //en.wikipedia.org/wiki/Comparison_of_code_generation_tools


6
それはましではありません。あなたの貴重な小さな非常に独自のコードは、他のブロックのコード生成ツールでは適切に管理できません。他のブロックはあなたの詳細について何も知らないからです。メタプログラミングの最も生産的な使用法は、ドメイン固有の言語を実装することです。名前が示すように、それらはあなたの問題のあるドメインに固有のものであり、あなた以外の人は実装できません。
SKロジック

@ SK-logic:ORM生成コードはどうですか?別のツール/ライブラリによって生成され、多くのプロジェクトニーズを満たします。
デビッド

@David、正直に言って、私は一般的なORMにあまり納得していません。私は過去に多くの問題を抱えていましたが、代わりに私自身の特定のORMを実装することにしばしば頼りました。
SKロジック

1
@Jordan、これらのツールはすべて具体的すぎます(さらに悪いことに、テキストベース、つまり設計上劣っています)。代わりに、適切なメタプログラミングについて話しています。
SKロジック

1
@AtillaOzgur、彼らは「非常に良い」、本当であり得る。しかし、それらはeDSLよりも優れているわけではありません。スタンドアロンのコード生成は、マクロメタプログラミングよりも明らかに制限が多く、柔軟性がはるかに低くなります。
SKロジック

16

古典的な例の1つは、lexとyaccです。彼らの主な目的は、あらゆる種類のパーサーを書くという面倒な作業を避けることです。途中で、多くのルールと状態を持つ複雑なパーサーを構築するのがはるかに速くなり、また、自分で転がすことによって生じる不意のミスをすべて回避します。

これは、アセンブラーを作成するツールであるcの背後にある考え方でもあります。同じことは、名前を付けたい高級言語にも当てはまります。コードを作成するツールには、いくつかの簡単なパラダイムがあります。

適切なIDEは、指先でドキュメントを提供したり、スマートな自動補完やコードスニペットを提供したりするのに役立ちます。IDEにはさまざまなテンプレートも含まれているため、プログラムを最初から開始する必要はありません。UMLダイアグラムを取得し、高水準言語でクラスをラフにするプログラムがあります。

最後に、問題セット内でコード生成用の独自のツールを作成できます。これが、lexとyaccが最初に始めた方法です。まさにこの理由から、あらゆる種類のドメイン固有の言語が存在します。ソリューションをわかりやすいコードで記述したり、一般的なアクティビティをまとめたり、単純なコマンドで複雑なセクションを作成したりするビルディングブロックを作成します。すべての問題の解決策を探しているのではなく、対処している特定の問題を簡単に定義するだけです。

ある意味では、バイナリ層の上で行うことはすべてコードの自動化です。


それは本当に素晴らしい眺めです。全体として、プログラマーが操作を容易にし、構文コードの詳細ではなく、より高いレベルのコーディングに集中するために使用しようとする多くの方法の1つにすぎません。
ホセファエティ

1
@Jose Faetiウィキペディアの記事en.wikipedia.org/wiki/Automatic_programmingには、さらに詳細に興味がある場合は、さまざまなツールへのリンクがあります。また、lexとyaccについても詳しく調べることをお勧めします。これらについては、さらに多くのドキュメントと説明があります。
スペンサーラス

十分に強力な言語(Cに対してC ++など)では、lexやyaccなどの外部ツールは不要です。
ケビンクライン

YACCは「いかなる種類のパーサー」も作成しません。これは、自動化されたヘルプなしでは適切に処理するのが非常に難しい特定の種類のパーサー(LALR)を記述します。別のタイプのパーサー(再帰降下)があります。これは、書き込みと正しい操作がはるかに簡単で、それに応じて、何が起こっているかを読み、理解するのが簡単です。
メイソンウィーラー

@MasonWheeler一種のパーサーは、広く正確ではない意味で問題を解決するために作成できる文法を指していました。1年後にそれを読んで、それは私が好きだったほど明確ではありません。ただし、LL(*)パーサーを作成して使用する方が簡単であるという点で、私はあなたに同意しません。
スペンサーラスブン

13

メタプログラミング

メタプログラミングは、多くのショップで物議を醸す技術です。その理由は、強力なツールのように、助けや傷の大きさが大きいからです。

長所

  • より表現力豊かで、記述および保守するコードが少ない(多くの場合、1桁以上)
  • コードで解決する問題のクラスに対する一貫性、より一貫した動作
  • 生産性が向上し、より大きな問題空間に対するソリューションのコードが少なくなります

短所

  • 複雑さ、コードが少なくても非常に複雑になる可能性があります
  • 一般に、安全性、場合によっては型安全性および静的解析が犠牲になります
  • バグはより多くの影響を与え、小さなエラーはより大きな影響を与えます

私はメタプログラミングのファンですが、長い間やっています。私にとって、コードサイズの縮小と一貫した動作のトレードオフは、リスクを補う以上のものです。コードが少ないということは、バグが少なく、維持するコードが少ないことを意味します。通常、私は非常に迅速に多くの機能を追加できます。

しかし、これはすべてのプログラマーがそれに取り組むべきだと思うという意味ではありません。私は、メタプログラミングによって生じる大きな問題を見て、修正しなければなりませんでした。通常、コンセプトを理解しておらず、機能を拡張しようとしたか、単にバグを修正しようとした人たちから。少なくとも詳細指向の特定のマインドセットが必要です。 メタプログラミングテクニックを使用するという質問は、チームの決定である必要があります。理解できないチームメンバーがいたり、気質がなかったり、チームメンバーがメタプログラミングを使用するべきではない場合。


便利な考慮事項をありがとう!メタプログラミングを使用して実装できる、本当にシンプルで基本的なタスクを提案してもらえますか?
ホセファエティ

ハハは、数年前にGCCで経験したエラーを思い出させてくれます。画面にエラーメッセージを表示する162行。再帰的なメタプログラミングFTW!
-deadalnix

6
メタプログラミングの複雑さは非常に過大評価されています。適切なツールを使用している限り、複雑なことはまったくありません。また、DSLは典型的な定型コードよりもデバッグと保守がはるかに簡単です。また、なぜ型安全性を犠牲にする必要があるのか​​理解できません-それはまったく逆であり、DSLにはドメイン固有の非常に効率的な型システムもあるかもしれません。
SKロジック

2
@ SK-logic:すべての言語がメタプログラミングをうまくサポートしているわけではありません。そのため、タイプセーフティなどが犠牲になる場合があります(Cなど)。また、メタプログラミングはDSLだけではありません。ディスパッチスタイルプログラミング、ジェネリック、カリー化、オブジェクト検査、動的アプリケーションなどが含まれます。複雑さに関しては、私たち(メタプログラミングの経験がある人)にとっては複雑ではないと言うのは簡単だと思います。私は、コードが実行されるすべてのケースを理解する他の闘争を見てきました。それは主に彼らの経験と関係する技術に依存します。
-Dietbuddha

@dietbuddha、詳しく説明してもらえますか、それがどのように実装されていても、DSLの型安全性を犠牲にするのはなぜですか?強力な型システムを持つ純粋なCでアドホックインタープリターを作成できます(たとえば、Hugsを参照)。ターゲット言語の型システムに依存することなく、すべての型チェックを行うCを対象とするコードジェネレーターを作成できます。複雑さの場合:ほとんどの人は不必要に複雑な方法でそれを行っていますが、「通常の」プログラミングと同じ設計手法をコード生成に適用できます。新しい知識はほとんど必要ありません。
SKロジック

9

ほとんどのコードはコードを記述します。たとえば、phpコードはhtmlの記述に役立ちます。php pdoライブラリは、SQL呼び出しの記述に役立ちます。ファイルI / O関数は、OSと通信するコードを記述します。通常の関数呼び出しでさえ、実行される別のコードブロックへの参照です。したがって、関数呼び出しはコードを記述しています。

大まかに言えば、コンピューティングは、ハードウェアに配線されたコードの物理的な現実に反して終了するスタックを再帰的に形成するコードを記述するコードを書くと考えることができます。


3
私はhtmlをプログラミング言語とは呼びません。文書の構文
サイモンベルゴ

3
@Simonは興味深い点です。私たちが使用するさまざまなコードには、さまざまな表現力があります。コードは、より弱い言語、より強い言語、または独自の言語に書き込むことができます。
ベン・ヘイリー

5

これを行う方法は、要件によって異なります。静的コード生成を使用していると仮定すると、すべてのインフラストラクチャを自分で記述することも、CodeSmithやMyGenerationなどの既存のジェネレーターを使用することもできます。これらを使用して、必要なテンプレートを作成するだけです。

これに関する最後のプロジェクトは、基本的なASP.NET CRUD画面でした(コード生成はこれに適しています)。このプロセスでは、エンティティをXMLファイルのメタデータとして定義しました。必要なさまざまなアーティファクト(エンティティクラス、リポジトリ、サービスクラス、asp.netコントロール、asp.netページなど)をカバーするテンプレートを作成します。生成プロセスを実行し、出力のスタイルを設定します。

テンプレートの作成には多少のオーバーヘッドがありますが、後続の同様のプロジェクトで再利用できます。同様に、基礎となるデータへの変更は、メタデータを変更し、生成を再実行して、変更をより簡単かつ迅速に実装することで処理されます。

テストに関して。これはテンプレートシステムであるため、プロセスの出力を最初に検証するのにしばらく時間をかける必要があります。テンプレートが間違っている場合、そのテンプレートからのすべての出力も同様に間違っています。これに満足したら、コードジェネレーターを使用してxmlメタデータから基本的なテストを作成し、特別なケースをカバーするように拡張することもできます。ただし、特定の事項に対応するためにコードテストを手動で行う必要がある場合があることを忘れないでください。コードを生成すると作業量が減り、完全になくなるわけではありません。


5

当社では、インターネットからダウンロードしたデータを使用してC ++またはC#クラスを実際に生成するツールを使用しています。これらのクラスはデータコンテナであり、リストに多数のオブジェクトが含まれています。


たとえばVisual StudioなどのIDEにあるコードスニペットのようなものはありますか?
ホセファエティ

@Joseこのツールは、HTML出力をクラスに変換するための単なるアプリケーションです。そのため、アプリケーションを起動するたびにデータをダウンロードする代わりに、一度ダウンロードしてクラスを作成します。
ホリ

5

メタプログラミングは長い間プログラミングの一部でした。コードを作成するSWIGやWYSIWYGデザイナーのようなツールだけでなく、Cのプリプロセッサ、またはC ++のテンプレートやC#/ Javaのジェネリックなどの言語内ツールも考慮してください。

実際、すべてのコンパイラは単なる別のメタプログラムであり、プログラムテキストを取り込んでマシンまたはVMコードを出力していると主張できます。そして、コンパイラなしの生活?うわ


そうですが、実際に生産性を向上させるために、独自のプログラミング言語で実際に実装するにはどうすればよいでしょうか?それは私が欠けているものです。
ホセファエティ

5

これが私の過去の具体例です。

私は、データアクセスにBDEを使用する約50MBのDelphiソースコードがあるサイトで働いていました。彼らは、OracleがBDEでサポートされている最高バージョン(正しく思い出せば8i)を超えてアップグレードできるように、Direct Oracle Accessの使用に切り替えたいと考えていました。

そのため、コーダーのチームにすべてのコンポーネントを手動で変更してすべてのフォームとデータモジュールを処理させる代わりに、次のようなPERLスクリプトを作成しました。

  1. DFM(フォームファイル)を解析し、すべてのTQuery、TTable、TStoredProcedureおよびTDatabaseオブジェクトを識別しました-リストに項目を保存します。

  2. PAS(コード)を解析し、オブジェクトの使用を特定しました-TQueryは更新または選択を行いましたか?また、IDEのフォームにドロップされるのではなく、コードで作成されたオブジェクトを識別しました。

  3. オブジェクトタイプを適切に変更するDFM&PASを書き直し(たとえば、SQLプロパティを "select * from"などに設定したTTable-> TOracleDataSet)およびメソッド呼び出し。また、必要に応じて、パラメータを閉じたり、開いたり、設定したりするためのメソッド呼び出しが追加されました。

要するに、6か月間働く5人以上の開発者の元の見積もりではなく、異なるコーディングスタイルを持つ異なるチームによって作成された異なるアプリケーションで動作するようにスクリプトを微調整する3週間の作業です。

そして、私がそのアプローチを使用することを考えた理由は、The Pragmatic Programmer


それは素晴らしいことです。数日前からPerlに取り組んでおり、「ワークスペースの作成」と入力するだけで、すべてのディレクトリ、ファイルなどを含むWeb開発用の基本的なワークスペースを生成する生産性ツールを作成しました!:)
ホセファエティ

1
@Joseそれがアイデアです。スクリプト言語を使用して、繰り返しを自動化します。これは、生産性が8倍に向上する1回限りの場合や、場合によっては何度も何度も時間がかかるものになります。
mcottle

4

あなたは例を求めます...

SQLを使用する場合、データベースを直接変更するのではなく、データベースの構造変更(テーブル、列、主キー、制約などの追加)を含む、必要な変更を行うスクリプトを実行する必要があります。多くのテーブルまたは列に対して同じアクションを同時に実行する必要が非常に頻繁にあり、それらを1つずつ実行するのは面倒です。目的の処理を実行する大きなスクリプトを出力する短いスクリプトタイムセーバー。

たとえば、DATEデータ型がMS SQl Serverに導入される前は、日付列の唯一の選択肢はDATETIMEであり、これには時間部分があります。これは、データの処理を少し難しくする時間部分です。Dateデータ型のバージョンにアップグレードするときに、時刻が常に00:00である列を更新することができます。数十または数百のDateTime列を持つデータベースでは、これは非常に時間がかかります。ただし、すべてのテーブルをクエリするスクリプトを作成して、DATETIMEのデータ型を持つすべての列をチェックして、時間が00:00以外であるかどうかを確認し、そうでない場合は変更するテーブル/列のALTERステートメントを作成するのは簡単ですDATEのデータ型。プレスト、コードを書くコード。


3

CL(Common Lips)マクロをご覧ください。私の意見では、まさにあなたが望むものです。唇はメタプログラミングに最適です。

また、私はお勧めNemerleをあなたが(マクロを含む)の完全なメタプログラミングをサポートして.NET力を持つようにしたい場合は

しかし、真のコード生成エンジンが必要な場合は、Apache thriftを見てください。


3

私はそのようなツールに取り組んでいます。特定のケースでは、データベース内の関数のシグネチャに基づいて、データレイヤーに基づいてVB.NETコードを生成します。

コードの生成方法がわからないため、コード生成の作業開始することは最初は困難ですが、ルールのセットを確立すると、生成されたコードは常にそれらのルールに基づいて生成できます、そのコードでの作業はそれほど難しくありません。もちろん、コード生成の複雑さとルールの数に応じて、タスクはより困難になる可能性があります。しかし、本質的には、自動コード生成は反復的なコーディングタスクに使用され、さまざまな高度なコードには使用されません。

出力のテストは2つあります。まず、コードがコンパイルされることを確認する必要がありますが、それは簡単です。次に、生成されたパラメーターに基づいて、出力が意図したとおりに動作することを確認する必要があります。その難易度は、生成するコードの複雑さによって異なります。

私が心から推奨しているのは、コードを繰り返し書くような気がするなら、時間に余裕があるということです。あなたがやっていることは生成されたコードではできないか考えてみてください。その場合(ほとんどの場合よりも繰り返しコードの場合)、何回拡張する必要があるかを考え、そのコードをわずかに変更し、その正確な種類のコードを何回書く必要があるかを考えます。これらのいずれかの答えが「多」である場合、そのコードのジェネレーターを作成することを真剣に検討する必要があります


IPPに役立つことを願っています


ご回答ありがとうございます!あなたの例のルールは実際にどのように実装されていますか?
ホセファエティ

1
すべてのルールを説明することはできませんが、いくつか例を示します。Oracleデータベースによって公開されたインターフェイスを解析し、Oracleインターフェイスの関数のシグネチャを考慮します。署名に基づいて、データレイヤー関数の名前を生成します。結果として常にデータベースからoracleデータテーブルを取得し、それを解析してデータの保存に使用する特別なオブジェクトタイプの配列に保存することがわかっています。また、DBの関数シグネチャの入力/出力パラメータに基づいて、我々は、我々が生成する関数に対応する入力および出力パラメータを追加するというように..
ヨアンポールPirau

3

HTMLを生成するJavaScriptコードを含むWebページを出力するPHPモジュールがあります。これが3つのレイヤーです。少年は読みにくい!

プログラミングクラスでは、ユーザーから数式文字列を取得して解析し、値を表示するプログラムを作成する必要がありました。最も印象的なソルバーは、ユーザー入力を取得してmain(){printf( "%d"、...);}にラップし、それをコンパイル、リンク、および実行するスクリプトを実行しました。彼はパーサーを書きませんでした!今日では、SQL SELECTステートメントでそれを行うことができます。

それはあなたが一緒に遊ぶべきツールであり、それが便利になる将来のある日のためにそれを保管しておきます。


それは実際に私が実装しようとしていたものと同じです!:)しかし、その後、Perlをオフラインでコーディングすることにしました。追加しようとしている機能がたくさんあります!
ホセファエティ

最大20層の言語から言語への変換を使用して、問題なくコードを記述しています。呼び出しスタックの深さは20層よりも複雑ではありません。ですから、「将来のある日のためにそれを便利に保管する」ツールであることに強く反対します-コード生成は常に便利です。
SKロジック

3

Prologを使用して、きちんとしたメタプログラミングソリューションを開発しました。メインアプリケーション(C ++の場合)は、実行時に問題の抽象的な定義をPrologアプリケーションに変換し、その後に委任されます。多くの場合、C ++で同等の機能を記述するのに時間がかかります。

このシナリオは、code-writing-code引数を支持する素晴らしいケースだと思います。


3

このテーマについてどう思いますか?

メタプログラミングは、多くの非生産的で非インテリジェントなコード行なしで特定の動作(ORMの実装など)を達成するのが難しいため、非動的言語に最も一般的に関連付けられています。

しかし、PHPなどのより動的な言語でさえ、コード生成は本当に命を救うことができ、大量の生産性を向上させることができます。現代のフレームワークでは、宣言する特定のビジネスオブジェクトのほとんどの一般的なモデル、フォーム、テスト、およびアクションを生成する足場が非常に一般的です。symfonyやRoRなどのフレームワークが非常に成功している理由の1つです。これらのコード生成ツールは一貫したコードを非常に迅速に作成し、プログラマの生産性を高めます。

Webサイトでは、相互作用のほとんどは4つの主なアクションを中心に展開されます。

  • 要素を作成する
  • 要素のセットを取得します(可能なフィルタリングを使用)
  • 新しい属性で要素を更新する
  • 一連の要素を削除する

少なくとも、この4つの主要なアクションを中心に展開するすべてのものは、コード生成ツールを使用して最大の生産性を達成することができます。

私の会社では、symfonyを使用しています。そのadmin-generatorは例外的なツールであり、実行時にコードを生成(およびキャッシュ)します。つまり、タスクや外部ツールを使用する必要さえありません新しいコードを生成するには、キャッシュを消去するだけです。この種のツールをCRUD操作に使用することを強くお勧めします。

しかし、symfonyの素晴らしい貢献者がしたことをするのは簡単なことではありません。私は自分でコード生成タスクをいくつか実装しましたが、ほとんど一貫性があり、ほとんどのコーナーケースをカバーする広範な実装で何かをするのは簡単ではありません。

生産性を本当に向上させるものですか?

メタプログラミングは低レベルの作業(フレームワーク、キャッシング、コンパイラなど)で非常に重要ですが、ビジネス層で作業を行う場合は細心の注意を払ってアプローチする必要があるものだと思います。

コード生成を使用することは、間違いなく主要な生産性向上になります。フレームワークを自分で構築しているのでなければ、独自のコード生成ツールを実装します。

本、ブログ、スライドショーなどのテーマに関する良いリソースは何ですか?

プログラミングを理解するのに最適なリソースは、常に優れたコメント付きのソースコードです。RubyOnRailsSymfonyの adminジェネレーターを調べるのは良いアイデアだと思います。


3

ここでの多くの回答は、一般にメタプログラミングとして知られているものを参照していますが、実際には、プログラムを理解または合成するプログラムに関する自動プログラミングとして知られるAIに関連する分野がありました[1]。

コンパイラー(またはメタプログラム、コードジェネレーター、トランスレーター、マクロシステムなど)は変換を処理し、変換の固定アルゴリズムを実行することで入力から出力を生成します。しかし、従来のコンパイラまたはメタプログラムは、リストの並べ替えの定義、説明、または例([5、3、9] => [3,5,9]など)が与えられた場合、並べ替えアルゴリズムを作成しません。このような問題は、この「自動プログラミング」分野の関心事です。

[1]-プログラム理解システムの進捗レポート ftp://db.stanford.edu/pub/cstr/reports/cs/.../CS-TR-74-444.pdfShare


2

メタプログラミングを維持するのは非常に困難です。最初はエレガントに見えますが、コーナーケースに遭遇し始めると、エラーは(生成されたコード上で)遅くキャッチされ、全体が使用/デバッグするのは悪夢になります。

私は主にpythonコードを書いてきましたが、私の経験では、この言語ではメタプログラミングは常に悪い選択です。退屈な通常の言語機能を使用して、いつでもリファクタリングできます。結果はファンキーではなくなりますが、一緒に暮らすのは簡単です。


どんな種類のコードで維持するのは非常に困難です。そして、正しい方法で行えば非常に簡単になります。メタプログラミングは、実際に桁違いに保守性を高めることができます。あなたのpythonの経験は、本当のメタプログラミングとはおそらく無関係です。なぜなら、Pythonはこの考え方にあまり適していないからです。しかし、Pythonを使用した場合でも、Tempitaライブラリを高い効率で使用し、Pythonの経験がほとんどないチームであっても、保守性の問題は一度もありませんでした。
SKロジック

Python ASTについてのあなたの意見に興味があります。メタプログラミングの目的でtempitaを使用しましたか?
サイモンベルゴ

これ(docs.python.org/library/ast.html)は非常にアドホックなASTであり、パーサーは最適化されていない、肥大化したツリーを提供します。そのようなASTを生成することもあまり便利ではありません。PythonとCの両方のコード(つまり、純粋なテキストベースのメタプログラミング)の生成にtempitaを使用しましたが、その特定のタスク(定型コード生成)でうまく機能しました。また、いくつかのXML高レベル記述からCコードを生成するためにPythonをよく使用しました。
SKロジック

2

OPはリソースを要求します。

DMS Software Reengineering Toolkitがおもしろいかもしれません。これは、カスタムプログラム分析および変換ツールを作成できるようにすることを目的とした、純粋なメタプログラミングツールです。

[OPの質問へのコメントに従うために、特定の変換ツールを構築するために使用される場合、DMSはコードを記述する、コードを記述する製品ラインです。]

DMSは、ターゲットプログラミング言語にとらわれない(独立ではない)ことでこれを実現します。DMSは、OSが標準のプログラミングタスク用に多種多様なサービスを提供するのと同様に、多種多様なメタプログラミングタスクに必要な標準サービスを提供します。これらのサービスには、強力な解析、抽象構文ツリーの自動構築、ツリーでのパターンマッチングと書き換え、多重継承、制御フロー、データフロー、ポイントツー、コールなどの厄介なスコープルールで言語を簡単に管理するシンボルテーブルライブラリが含まれますグラフ分析。処理する特定の言語がない場合、これは意味がないため、DMSはこれらの一般的な機械に関連付けられた言語定義を受け入れ、言語固有の解析、AST構築、ターゲットを使用したターゲット言語固有のパターンマッチング/リライトを生成します。言語構文、

また、OSのように、DMSは作成する(メタ)プログラムに関する意見や制約がほとんどないように設計されています。つまり、メトリックの抽出、デッドコードの検出、アスペクトウィーバーの実装、翻訳など、さまざまな目的に使用できます。言語、DSLからのコード生成、大規模アプリケーションの再構築。(DMSはこれらのすべてのタスクに既に使用されています)。

langaugeリファレンスマニュアルのすべてをエンコードすることに時間を費やしたくない場合は、堅牢な言語定義が必要です(JavaとC ++の意味を考えてください)。DMSは、完全な言語定義のライブラリを利用可能にすることで、この問題を解決します。ここでのアナログは、OS用のデータベースを持っているようなものです。データベース中心のアプリケーションを作成するためにそれらの1つを実装する必要はありません。


2

MITコース6.916:革新的なWebサービスのソフトウェアエンジニアリング(http://philip.greenspun.com/teaching/psets/ps4/ps4.adp)のPhilip Greenspunの問題セット4を参照してください。

その目的は、「学生にメタデータの長所を教えます。具体的には、Webサービスの要件を正式に表現する方法を学習し、そのサービスを実装するコンピュータープログラムを生成するコンピュータープログラムを構築します」。

これは、ArsDigita(http://en.wikipedia.org/wiki/ArsDigita)候補者が最初のバブルで解決するために必要だった潜在的な問題セットの1つです。

pset内のPhilipが参照している「SQL for Web Nerds」の本は(http://philip.greenspun.com/sql/)に移動しました。


2

2001年またはその前後に、ビジネスオブジェクトとデータオブジェクトを広範囲に使用するプロジェクトに取り組み始めました。私はフロントエンドWebサイトを構築するつもりでしたが、ビジネスレイヤーとデータアクセスレイヤーが完全に開発されていないため、親指をいじるだけでハングアップしました。その数週間後、私はそれらのレイヤーが何をしているのかをじっと見始めました。基本的に、データのフィールドに対応するプロパティを持つオブジェクトのコレクションとしてストアドプロシージャから返されたデータを公開するか、データベーステーブルに保存するために入力パラメータを取得してストアドプロシージャに送信していました。2つの層の間で多くのシリアル化/逆シリアル化が行われ、Microsoft Transaction Serverが関与し、IDL / ODLタイプライブラリがありましたが、すべてパターンに適合していました。

2週間後、IDL / ODLをダンプし、ビジネスオブジェクトとデータオブジェクトもダンプするコードジェネレーターを作成しました。これらのオブジェクトのデバッグとテストのポイントに到達するのに、ビジネスおよびデータレイヤーオブジェクトを構築する人が2年かかりました。2週間でコード生成を行ったところ、同じ出力が得られましたが、すべて生成されているため、バグはほとんどありませんでした。

そのコードジェネレーター(下位レベルのCASEツール)は、原則が非常に単純だったため、約8年から10年間、さまざまな反復を繰り返して行ってきました。コーディングの繰り返しが多く、一度正しく設定すれば、もう心配する必要はありません。

そのため、特にコーディングが繰り返し行われ、明確に定義されたパターンに適合する場合は、コードジェネレーターを使用します。

RegXマクロを使用して同様のことを行うか、Excelの数式を使用して同様のことを行うことを知っています(これも行います)。


2

メタプログラミングの例

AuthorityというRuby認証ライブラリがあります。開発者は、current_user.can_read?(@post)やなどのメソッドを使用して、アプリで質問をすることができます@post.readable_by?(current_user)。これらの質問には、中央集中型の承認者クラスが回答します。

これは重要な部分です。ユーザーの構成が表示されるまで、機関はどのメソッドを定義するかを知りません。ユーザー構成には次のものが含まれます。

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}

その場合、のようなメソッドが必要current_user.can_microwave?(@post)です。

メタプログラミングは、これが可能に:コンフィギュレーションを読んだ後、私は知って定義するメソッド

Authority.verbs.each do |verb|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1 # allows for a nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  RUBY
end
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.