2010-02-23 78 views
10

也許我受限於我對動態語言的體驗(Ruby on Netbeans和Eclipse上的Groovy),但在我看來,動態語言的本質使得不可能重構(重命名方法,類,推送,自動關閉等)。在動態語言中是否可以自動重構?

是否有可能在任何動態語言(使用任何IDE /工具)重構AUTOMATICALLY?我特別感興趣的是Ruby,Python和Groovy,以及重構與所有Java IDE中100%自動重構的比較。

回答

16

鑑於使用動態語言(Smalltalk)自動重構爲發明,我不得不說「是」。

特別是John Brant,Don Roberts和Ralph Johnson開發了Refactoring Browser這是Squeak的核心工具之一。我們的Google-fu今天很弱,但你可以試試看這篇文章:Don Roberts,John Brant和Ralph Johnson,Smalltalk的重構工具,「對象系統的理論與實踐」,(3)4 ,1997.

+0

雖然這個歷史記錄是groovy(原諒雙關語),我不想弄清楚是否有可能。即使在Ruby中,我們也有「自動重構」,但實際上它不起作用。在Netbeans中甚至有警告,但實際情況非常暗淡。另外,我不知道是否在Smalltalk中聲明瞭所有類型,這將有助於重構。在Ruby中你不會這麼做,這是使它變得如此困難的原因之一。 – 2010-02-23 13:04:12

+2

對不起,我不是故意只給一個歷史筆記。我的意思是建議重構瀏覽器是許多Smalltalk IDE中的標準工具 – 2010-02-23 14:02:24

13

Smalltalk沒有聲明任何類型。自1995年以來,重構瀏覽器已成功地在商業代碼中執行了正確的重構,並且幾乎包含在當前的所有Smalltalk IDE中。 - Don Roberts

+2

感謝Don,現在我只需要在Smalltalk中找到一份工作。如何在不聲明類型的情況下進行重構(原諒我的無知)? – 2010-02-23 13:54:52

9

自動重構是Smalltalk中發明的,它是一種高度動態的語言。 從此以後,它就像一種魅力。

您可以自己嘗試自己在一個自由的Smalltalk版本(例如http://pharo-project.org

在動態語言也可以編寫腳本的重構或查詢 系統。簡單的例子來獲得測試類的數量:

的TestCase allSubclasses大小

1

同上關於重構瀏覽器的點...它是在Smalltalk中非常有效。然而,我想有沒有類型信息是不可能的重構的某些類型(不管是通過語言中的顯式類型註釋還是通過動態語言中的某種形式的類型推斷都是不相關的)。舉一個例子:在Smalltalk中重命名一個方法時,它會重命名該方法的所有實現者和發送者,這通常是很好的,但有時候是不可取的。如果你有關於變量的類型信息,那麼你可以將重命名的範圍限制在當前類層次結構中的實現者以及當消息發送到聲明爲該層次結構類型的變量時的所有發送者(但是,我可以想象情景即使是類型聲明,也會導致分解併產生不良結果)。

+0

謝謝你。這是什麼意思「它會重命名所有實現者和發送者」?全球範圍的方法(或類似的東西?)? – 2010-02-24 21:16:52

+0

另外,它是Smalltalk的日子還是什麼?我永遠不會明白爲什麼這個問題會沿着小岔路線走下去。你有沒有在某個地方看到鏈接?它更多的是關於Python,Ruby和Groovy,但ST作爲一個例子顯然是有效的。 – 2010-02-24 21:46:24

+0

@yar:當然,方法是全局範圍的。在Python和Ruby中必須是相同的,但是如果一個方法接受一個參數併發送一個消息給/調用參數的一個方法,它將適用於實現該方法的所有類,所以重命名,比如說,一個調用站點將意味着重命名所有呼叫站點和實現。只有當你運行該程序時,你才知道哪些重命名子集仍然可以工作。 – quamrana 2010-02-25 17:50:39

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到字符串改變一個變量,你在所有的地方是仍然期待INT錯誤:

String wasInt; 
out = 3 + wasInt; 

對於解釋型語言,在運行時您可能不會看到它。

相關問題