2

C では、実行可能ファイルを生成し、大規模な名前変更のみのリファクタリングを実行してから、実行可能ファイルを再度比較して、実行可能ファイルが変更されていないことを確認できました。これは、リファクタリングによって何も壊れないようにするのに非常に便利でした。

Ruby、特にRailsアプリで似たようなことをした人はいますか? 戦略と方法は高く評価されます。理想的には、純粋にバイトコードであり、名前の変更によって変更されていない、ある種の単一のファイルを出力するスクリプトを実行できます。ここでは JRuby または Rubinus が役立つと思います。

4

2 に答える 2

2

興味深い質問です。少なくとも名前変更リファクタリングの特定のケースでは、この回帰戦略から得られる決定的な「はい」の答えが気に入っています。

私は、あなたが ruby​​ をコンパイルできるかどうか (または、少なくとも .NET のようなものなしでサブセットをコンパイルできるかどうか) を判断できるほど専門家ではありませんが、以下evalにいくつかのヒントがあるようです:

完全なコンパイルが不可能であると仮定すると、抽象的な解釈アプローチはどうでしょうか? Ruby を解析して AST にし、AST からある種の C コードを発行してから、C コードをコンパイルすることができます。C コードは、Ruby コードの動作を完全にキャプチャする必要はありません。ルビが異なるときはいつでも、コンパイル可能であり、異なるものである必要があるだけです。(実際に実行すると、意味不明な結果になるか、またはすぐにメモリ違反エラーが発生する可能性があります。)

簡単な例として、Ruby は乗算をサポートし、C はサポートしていないとします。次に、静的mult関数を C コードに含めて from: a = b + c*d to に 変換するa = b + mult(c,d) と、結果としてコンパイルされたコードは、名前のリファクタリングでは不変になりますが、他の種類の変更では矛盾が生じます。mult関数は実際に乗算を実装する必要はありません。代わりに次のいずれかを使用できます。

static int mult( int a, int b ) { return a + b; } // pretty close
static int mult( int a, int b ) { return *0; } // not close at all, but still sufficient

C コンパイラが定義をインライン化しない限り、必要な不変性が得られます。コンパイルできない ruby​​ 構造から、機能は劣るが明確な C 構造への同様の変換は、オブジェクト操作などに有効であり、クラス操作を C 構造参照にマッピングします。重要な点は、実際の動作を犠牲にしながら、命名関係をそのまま維持したいということです。

(Rubyコードのすべてのクラスとプロパティ名にちなんで名付けられたメンバー(同じ構造体型へのすべてのポインター)を持つ単一のC構造体で何かできるかどうか疑問に思います.クラスとオブジェクトの操作は、を使用したネストされた逆参照操作に対応します.この単一の構造。単なる概念です。)

正確なマッピングを定式化できない場合でも、いくつかの小さな違いを見逃す不正確なマッピングでも、元の名前のリファクタリングの信頼性を高めるのに十分な場合があります。

このようなスキームを実装する最も簡単な方法は、(ruby AST から C ではなく) バイト コードから C にマップすることかもしれません。これにより、多くの解析が節約されますが、マッピングの理解と検証が難しくなります。

于 2012-09-23T03:32:41.390 に答える
2

この戦略は Ruby ではうまくいかないと思います。コンパイラが名前を破棄する C とは異なり、Ruby で名前を付けるほとんどのものには、その名前が付けられます。これには、クラス、モジュール、定数、およびインスタンス変数が含まれます。

自動化された単体テストと統合テストは、Ruby リファクタリングをサポートする方法です。

于 2012-09-01T12:35:07.443 に答える