2012-09-01 17 views
2

在C,我可以生成一个可执行文件,做了广泛的命名只是重构,然后再比较可执行文件,以确认该可执行文件并没有改变,这是非常方便确保重构没有破坏任何东西如何前和重构后的比较Rails的“可执行文件”?

有没有人做过类似于Ruby的任何事情,尤其是Rails应用程序?理想情况下,我可以运行脚本来输出某种类型的单个文件纯粹的字节码并没有被命名的改变而改变。我猜,JRuby或Rubinus会在这里有所帮助。

回答

2

我不认为这种策略对Ruby工作。不像C,其中编译器扔把名字拿走,你用Ruby命名的大部分东西都带着这个名字。这包括类,模块,常量和实例变量。

自动化的单元和集成测试是支持Ruby重构的方式。

+0

没有什么比测试。 – DGM

+0

实际上,没有什么比比较.exe和看到他们完全相同,保证没有什么不同,而不是相信测试覆盖;-)。我是写测试的坚定信徒,但希望能够对具有不良测试覆盖率的庞大遗留应用程序进行简单的重命名重构,并且我的方法更快更准确地捕获更改。这是我的问题的重点。 –

2

有趣的问题 - 我喜欢明确的“是”的回答,你可以从这个回归的策略得到,至少在重命名重构的具体情况。

我没有足够的专家来告诉你是否可以编译红宝石(或至少一个子集,没有之类的东西eval),但似乎有一些提示为:

假设完整的编译是不可能的,何谈一个抽象的解释方法呢?你可以将红宝石解析为AST,从AST发出一些C代码,然后编译C代码。 C代码不需要完全捕获Ruby代码的行为。它只需要可编译,并且在红宝石截然不同的时候就是明显的。 (实际运行它可能会导致乱码,或者立即内存冲突错误。)

举一个简单的例子,假设红宝石支持乘法和C没有。然后,你可以包括静态mult函数在C代码和翻译来自: a = b + c*da = 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结构引用。关键在于你想保持命名关系不变而牺牲实际行为。我不知道你是否可以用一个单一的C结构来做一些事情,这些C结构有成员(所有指向相同结构类型的指针),它们以ruby代码中的所有类和属性名命名,然后类和对象操作将对应于使用这种单一结构的嵌套解引用操作。只是一个概念。)

即使你不能制定一个精确的映射,一个不精确的映射会遗漏一些细微的差别,可能仍然足以提高对原始名称重构的信心。

实现这种方案的最快方法可能是从字节码映射到C(而不是从红宝石AST到C)。这将节省很多解析,但映射将更难以理解和验证。