興味深い質問です。少なくとも名前変更リファクタリングの特定のケースでは、この回帰戦略から得られる決定的な「はい」の答えが気に入っています。
私は、あなたが 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 にマップすることかもしれません。これにより、多くの解析が節約されますが、マッピングの理解と検証が難しくなります。