views:

367

answers:

4

Perhaps I am limited by my experience with dynamic languages (Ruby on Netbeans and Groovy on Eclipse), but it seems to me that the nature of dynamic languages makes it impossible to refactor (renaming methods, classes, pushing-up, pulling-down, etc.) automatically.

Is it possible to refactor AUTOMATICALLY in any dynamic language (with any IDE/tool)? I am especially interested in Ruby, Python and Groovy, and how the refactoring compares to the 100% automatic refactoring available in all Java IDEs.

+13  A: 

Given that automatic refactoring was invented in a dynamic language (Smalltalk), I would have to say "Yes".

In particular, John Brant, Don Roberts and Ralph Johnson developed the Refactoring Browser which is one of the core tools in, for instance, Squeak.

My Google-fu is weak today, but you could try find this paper: Don Roberts, John Brant, and Ralph Johnson, A Refactoring Tool for Smalltalk, "The Theory and Practice of Object Systems", (3) 4, 1997.

Frank Shearar
while this historical note is groovy (excuse the pun), I'm not trying to figure out if it's possible whatsoever. Even in Ruby we have "automatic refactoring" but in practice it doesn't work. In Netbeans there's even a warning, but the reality is quite bleak. Also, I don't know if you declare all types in Smalltalk, which would help refactoring. In Ruby you don't, which is one of the things that makes it so difficult.
Yar
Sorry, I didn't mean to only give a historical note. I meant to suggest that the Refactoring Browser's a standard tool in many Smalltalk IDEs
Frank Shearar
+9  A: 

Smalltalk does not declare any types. The Refactoring Browser has successfully performed correct refactorings in commercial code since 1995 and is incorporated in nearly all current Smalltalk IDE's. - Don Roberts

Don Roberts
Thanks Don, now I'd just need to get a job working in Smalltalk. How can it do refactoring without declaring types (excuse my ignorance)?
Yar
+8  A: 

Automatic Refactoring was invented in Smalltalk, a highly dynamic language. And it works like a charm ever since.

You can try yourself in a free Smalltalk version (for instance http://pharo-project.org)

In a dynamic language you can also script refactorings yourself or query the system. Simple example to get the number of Test classes:

TestCase allSubclasses size

Smalltalker
+1  A: 

Ditto the points about the Refactoring Browser...it is highly effective in Smalltalk. However, I imagine there are certain types of refactoring that would be impossible without type information (whether obtain by explicit type annotation in the language or through some form of type inferencing in a dynamic language is irrelevant). One example: when renaming a method in Smalltalk, it will rename all implementors and senders of that method, which most often is just fine, but is sometimes undesirable. If you had type information on variables, you could scope the rename to just the implementors in the current class hierarchy and all senders when the message is being sent to a variable declared to be of a type in that hierarchy (however, I could imagine scenarios where even with type declaration, that would break down and produce undesirable results).

Stephen
thanks for that. What does this mean "it will rename all implementors and senders of that method"? Are methods globally scoped (or something like that?)?
Yar
Also, is it Smalltalk day or something? I'll never understand why this question went down the smalltalk route. Did you see a link somewhere? It's kind of more about Python, Ruby and Groovy, but ST is obviously valid as a case.
Yar
@yar: Sure, methods are globally scoped. Must be the same in Python and Ruby, but if a method takes a parameter and sends a message to/calls a method on the parameter, it will work for all classes that implement that method, so renaming, say, one call site will mean renaming all call sites and implementations. Only you know which subset of renames will still work when you run the program.
quamrana
@quamrana perhaps I don't know what we're talking about. In Ruby, methods on a class are on that class :)... but then they can be mixed-in from other places.
Yar
@yar: Sure, methods on any class have a name, and anywhere that calls a method, in a dynamic language, doesn't know the class of the object its calling the method on. It just knows the name of the method. So it doesn't matter which classes have a method of a given name, nor the implementations of them, just the spelling of the name.
quamrana
@quamrana so do you tend to use unique method names to help refactoring? In ruby this might help but be annoying
Yar
I don't necessarily use unique method names. Sometimes I just change the name of a method and run all the tests to see which call sites are affected.
quamrana
@yar The Smalltalk Day thing's probably my fault. I moaned that I was turning into a Grouchy Old Man on squeak-dev because of your question, and next thing Ralph Johnson was mailing Don Roberts and John Brant, and I guess the Squeakers just jumped all over the question.
Frank Shearar
aha! I knew there was an explanation for this, coincidence made no sense.
Yar