10

也许我受到动态语言(Netbeans 上的 Ruby 和 Eclipse 上的 Groovy)经验的限制,但在我看来,动态语言的本质使得重构变得不可能(重命名方法、类、上推、下拉、等)自动。

是否可以用任何动态语言(使用任何 IDE/工具)自动重构?我对 Ruby、Python 和 Groovy 以及重构与所有 Java IDE 中可用的 100% 自动重构的比较特别感兴趣。

4

5 回答 5

16

鉴于自动重构是用动态语言(Smalltalk)发明的,我不得不说“是”。

特别是,John Brant、Don Roberts 和 Ralph Johnson 开发了Refactoring Browser,它是 Squeak 等的核心工具之一。

我的 Google-fu 今天很弱,但您可以尝试查找这篇论文:Don Roberts、John Brant 和 Ralph Johnson,A Refactoring Tool for Smalltalk,“对象系统的理论与实践”,(3) 4,1997。

于 2010-02-23T12:10:13.633 回答
13

Smalltalk 不声明任何类型。自 1995 年以来,Refactoring Browser 已经成功地在商业代码中执行了正确的重构,并且几乎包含在所有当前的 Smalltalk IDE 中。- 唐·罗伯茨

于 2010-02-23T13:21:08.263 回答
9

自动重构是在 Smalltalk 中发明的,这是一种高度动态的语言。从那以后,它就像一种魅力。

您可以尝试使用免费的 Smalltalk 版本(例如http://pharo-project.org

在动态语言中,您还可以自己编写重构脚本或查询系统。获取测试类数量的简单示例:

测试用例所有子类大小

于 2010-02-23T13:35:45.527 回答
2

我想知道同样的事情。我不是编译器/解释器作者,但我认为答案是不可能让它完美。但是,在大多数情况下,您可以得到正确的。

首先,我要将名称“动态”语言更改为“解释”语言,这就是我对 Ruby、Javascript 等的看法。解释语言倾向于利用运行时功能。

例如,大多数脚本语言允许以下

-- pseudo-code but you get the idea
eval("echo(a)");

我只是“跑”了一个字符串!您还必须重构该字符串。如果没有变量a,a会是一个变量吗?或者这种语言是否允许您打印不带引号的字符a?

我想相信这种编码可能是个例外,而且你几乎总是会得到很好的重构。不幸的是,当我查看脚本语言的库时,它们通常会遇到此类异常,甚至可能基于它们的架构。

或者提高一点赌注:

def functionThatAssumesInputWillCreateX(input)
    eval(input)
    echo(x)


def functionWithUnknownParms( ... )
   eval(argv[1]);

至少当您重构 Java 并将变量从 int 更改为 string 时,您仍然会在所有期待 int 的地方得到错误:

String wasInt;
out = 3 + wasInt;

对于解释型语言,您可能要到运行时才能看到这一点。

于 2012-02-22T21:18:43.923 回答
1

同上关于重构浏览器的观点......它在 Smalltalk 中非常有效。但是,我想如果没有类型信息,某些类型的重构是不可能的(无论是通过语言中的显式类型注释还是通过动态语言中的某种形式的类型推断来获得都无关紧要)。一个例子:在 Smalltalk 中重命名一个方法时,它会重命名该方法的所有实现者和发送者,这通常很好,但有时是不可取的。如果您有关于变量的类型信息,您可以将重命名的范围仅限于当前类层次结构中的实现者以及当消息被发送到声明为该层次结构中的类型的变量时的所有发送者(但是,我可以想象场景即使有类型声明,

于 2010-02-24T21:02:49.270 回答