Refactoring Browser

The RefactoringBrowser is a tool that automates some ReFactorings for Smalltalk. See http://st-www.cs.uiuc.edu/users/brant/Refactory/RefactoringBrowser.html


This is absolutely the greatest piece of programming software to come out since the original Smalltalk browser. It completely changes the way you think about programming. All those niggling little "well, I should change this name but..." thoughts go away, because you just change the name because there is always a single menu item to just change the name.

When I started using it, I spent about two hours refactoring at my old pace. I would do a refactoring, then just kind of stare off into space for the five minutes it would have taken me to do the refactoring by hand, then do another, stare into space again. After a while, I caught myself and realized that I had to learn to think BiggerRefactoringThoughts, and think them faster. Now I use probably half and half refactoring and entering new code, all at the same speed (I should instrument to measure this). -- KentBeck


Discussion about using shell tools to rename symbols moved to ReadWriteGrep


Changing names is the least of its tricks. Some others are: These three together are extremely powerful. For example, if I notice

 area := aRectangle right - aRectangle left * (aRectangle bottom - aRectangle top).
	....

I select the statement to the right of the assignment and "extract method", naming the new method areaOf:. Now I have:

	area := self areaOf: aRectangle.
	...

areaOf: aRectangle ^aRectangle right - aRectangle left * (aRectangle bottom - aRectangle top)

Now I notice that aRectangle cares a lot more about this message than I do, so I "move to component" and choose aRectangle (other possible choices are my instance variables). The type inference stuff generally does a great job of determining the class or classes of aRectangle, or I can type the classes in. I choose "Rectangle", and name the new method "area". Now I have:

	area := self areaOf: aRectangle.
	...

areaOf: aRectangle ^aRectangle area

Rectangle>>area ^self right - self left * (self bottom - self top)

Now, areaOf: isn't doing me much good, so I go to the original method, select "areaOf:" and "inline method". Now I have:

	area := aRectangle area.
	...

Rectangle>>area ^self right - self left * (self bottom - self top)

Now I can imagine extracting "self right - self left" into "width", etc.

The best thing about Refactory is how safe it is. As long as you don't manually edit the source code, you are nearly guaranteed (modulo things like choosing the wrong class for a "move to component") that you won't change the semantics of the program. The more I use it, the more aggressive I am slamming logic around until it makes sense.

Some other cool tricks: With unlimited undo, you can bravely try experiments that might not pan out.

-- KentBeck


Using search/replace to perform renaming refactorings ignores the fact that every place the name occurs shouldn't always be renamed (the syntax of the methods). This is especially true for badly named variables. For example, one person might have named a variable "i" instead of a more descriptive name such as "minimalElementIndex". Now if you were to replace "i" with "minimalElementIndex" using search/replace, your program would no longer work since you probably refer to some type such as "minimalElementIndexnt" instead of "int". -- JohnBrant

'' I found myself with a lot of longerfaces once when I did this. -- AnonymousCoward ''

... and if the "i" being replaced above were in a quoted string e.g
    String name = String("Brat Simpson");
you'd get
    StrminimalElementIndexng name = StrminimalElementIndexng("Brat SminimalElementIndexntmpson");

You'd at least need to do lexical analysis to work out which lexemes need to be renamed (and apply the correct kind of substitution.)


My understanding with the refactoring browser is that, unlike any script you will write in an editor, it guarantees that the code won't change its meaning. I got this message from one of the browser authors when I was asking why it didn't let me tune the accessor code that it generates when changing from raw instance variables to accessors. His answer was, "well that changes the meaning of the code, so it is not refactoring, even if it is useful." Ahhh, I thought, and understood something about refactoring. -- AlistairCockburn


Don Roberts, John Brant, and Ralph Johnson, A Refactoring Tool for Smalltalk, "The Theory and Practice of Object Systems", (3) 4, 1997.
How does the RefactoringBrowser safely refactor without type information? For example, doesn't it need to know what objects are of a particular class in order to rename a method of that class? Does it just guess? -- KaPingYee

It does not just guess. It looks for special cases. Almost always one of the special cases applies. But sometimes it will tell you that it cannot perform a refactoring.

We originally thought that the lack of static type-checking would make it hard to build a refactoring browser for Smalltalk. Lack of type information is a disadvantage, but the advantages of Smalltalk made it a lot easier to make a refactoring browser for Smalltalk than it would have have been for C++ or Java.

-- RalphJohnson


Has any work been done on generalizing this, or making a C/C++/Java Refactoring Browser? Naive optimism would lead me to think that this would not be an overwhelming effort. -- Pete Hardie

I think it would be doable for Java. A Refactoring Browser that would work for the whole C++ language, and not some sane subset, would probably be AiComplete. Just think of all the possibilities for creative use of macros and templates. -- StephanHouben

I use emacs and JDE quite a lot for writing Java code. Maybe it would be possible to use EmacsLisp to write refactoring utilities. I might have a go at it when (if) I have the time. -- BernardMichaelHurley

Actually, there are a few refactoring tools available for Java... see RefactoringBrowserForJava. However, these tools support only a small portion of the refactorings available in the original RefactoringBrowser for Smalltalk.


I've never used the RefactoringBrowser (I don't know SmallTalk). I am familiar with JRefactory. JRefactory integrates into various IDEs. Is the RefactoringBrowser a stand-alone tool?

I'm quite new to Smalltalk myself (downloaded VisualWorks just last week), but as I understand it, any implementation of Smalltalk includes a complete development environment in which all code is edited, and the RefactoringBrowser runs inside this environment. There are some interesting technical reasons for this, but I'm afraid I don't understand them well enough to explain at all coherently - perhaps some more experienced Smalltalker could help?


Has there been any work in refactoring browsers for FunctionalProgramming languages such as CommonLisp? It seems that the existence of closures would make operations like add/remove parameter quite difficult to perform safely in the general case, and difficult even to be sure of the safety of.


ThereIsNoRefactoringBrowserForCpp


Check out EclipseIde http://www.eclipse.org, IntellijIdea http://www.intellij.com/idea.


Speaking of which, how do the refactoring capabilities of EclipseIde and IntellijIdea compare to RefactoringBrowser?


If the code-units (routines, methods, classes) were stored in a database, then renaming would be a simple query. GreencoddsTenthRuleOfProgramming again. Something else to explore: if auto-generated unit ID's were used instead of names by the software-engine, perhaps propagation-based renaming would not be needed. Propagation renaming leans toward a OnceAndOnlyOnce violation. If you change/rename your primary key often, auto-ID's may be the better approach. See TableOrientedCodeManagement. -- top


Python has a RefactoringBrowser, BicycleRepairMan.


Prolog also has a RefactoringBrowser, called ViPReSS, integrated with the VIM editor.


CategoryRefactoringBrowser

EditText of this page (last edited April 10, 2012) or FindPage with title or text search