On: Upcoming Gig: Startup Camp
From: Tim Bray
Is this thing on?
On: Dynamic-Language IDEs
From: Clayton Wheeler
As long as you're instrumenting what goes on in the test run, you probably want to do some tracing to track your test coverage, too, and maybe color the untested bits of code amber so it's obvious what isn't getting exercised. Of course, I wonder if I couldn't just jam that into XEmacs...
Hi. The comment system doesn't work with Internet Explorer 6. The comments are displayed fine, but the link to the comment form doesn't display ("Please feel free to contribute a comment on this fragment.")
On: Upcoming Gig: Zend PHP Conference
From: Keith Casey
Actually, I - and one of my lead developers - are a couple of those people. We'll both be attending Zend after I speak at DC PHP, but we're both working with the NYRUG to get a small conference happening on this end.
If you have a chance while you're at Zend, I'd love to get together and buy you a Beer of Appreciation. If you're willing, I'd also love an interview for my group software development blog CodeSnipers: http://codesnipers.com/
From: Paul Hoffman
For some value of "on", yes.
From: Arkaitz Bitorika
I had the same idea myself a while ago! The widespread use of test driven development with dynamic languages should allow really advanced IDE functionality without needing any explicit/static typing language. I can envision an environment that keeps test code constantly running in the background, providing information to the programmer for refactoring, profiling, etc. We have IDEs that auto-compile everything as soon as it's changed now, how long before IDEs auto-run test code and use runtime information in smart ways?
From: Reinier Zwitserloot
Summary: Are you nuts? Short of 100% code coverage any refactorings are always an unknown, and any bugs caused by it will by definition not be caught by any of your unit tests. Reaching 100% code coverage itself is waaaaaaaaaaaaaaaaaaaaaaaaaaaaay (I cannot stress enough by how many factors!) more work compared to the very mild job of adding types to all your declarations, something your IDE practically does for you, I might add. Not to mention the time it saves you on debugging.
I'm beginning to believe that python/ruby folk are so obsessed with unit tests exactly because they can't trust their compiler any farther than they can throw it, because it can't help but see your code as a pile of text instead of a structured set of links.
I do "FindUsage" all the time without an IDE: I just delete the method and run javac. I *know* the compiler is going to get it right.
As with everything else: it's all be done before:
Smalltalk. Infact refactoring was pioneered (like many other things, oop, gui, unit testing, agile/xp ...) in Smalltalk!
Smalltalk has 30 years of experience making the Ruby object model fast.
From: Damien Pollet
There is a package an Smalltalk that does this kind of dynamic type guessing; you might want to have a look (in fact I should too :-] ). It's available at least in Squeak (http://www.squeak.org) and VisualWorks (http://www.cincomsmalltalk.com) and is named RoelTyper.
From: Isaac Gouy
Tim Bray wrote "If you’re going to rename a method or a class or extract an interface"
iirc the problem is rename method / safe-remove method. (Don't understand why rename class would be a problem.)
anonymous wrote "I just delete the method and run javac"
What if the method was also implemented in a superclass?
From: Cedric Beust
Smalltalker: The Smalltalk IDE never did "true" renaming, only a search/replace. It might have been fine 20 years ago when everything was simpler, it's not going to fly today.
Tim: As you probably already know, this approach is simply not realistic. If you have anything less than 100% coverage (which, I contend, is probably 100% of software projects out there), the refactoring remains unpredictible and is guaranteed to break your code. Who wants a refactoring IDE that "works most of the time"?
The bottom line is that IDE's for dynamic languages will *never* be able to perform certain refactorings, such as renaming. It's just part of the trade-off of using such languages (and one reason why I'm convinced that they are not suited for large-scale software development).
From: Alan Green
I would have been disappointed not to have seen some Smalltalk person or another comment already. (S)he does have a good point, though, anyone setting off to provide IDE support for dynamic languages would do well to take a good look at the the various Smalltalk IDEs first, just to see what worked and what didn't work.
From: Charles Oliver Nutter
This is an interesting way of gathering information for refactoring. I'll break down a few possibilities and difficulties as I see them:
- We can gather information both from unit tests and from full-on runs if we run within an instrumented runtime. I don't think that would be difficult to do; in the JRuby project we've had multiple proposals and ideas on how to speed up dynamic invocation by gathering exactly this sort of information.
- By tracking actual types called at runtime we would avoid a much more expensive static analysis of the code. It would be possible to do an ahead-of-time analysis to track types as they move through a system, but it would be difficult to do accurately and quickly. The runtime-data approach may work better in some respects.
- Knowing when to invalidate that data would require that a separate component be examining code as it is edited. For example, we would have to keep information gathered from each running file separate, so that if a file changed we could throw out that piece of information. That might require more work to thread together all those separate pieces of information into something useful for refactoring, or to regenerate that "something useful" after every change, given what we still know.
- The longer you go without running, the less accurate the gathered information will be. Obviously we all know you should run unit tests frequently, but if you're working on a particularly difficult change, test runs may be more infrequent.
- We would want some way for the refactoring to feed back into the gathered information. If we did a "rename method" that affected 70% of our files, we would not want to have to throw out all information gathered.
I think runtime information will be a major component to any refactoring IDE, but I'm still convinced we'll have to combine dynamic runtime information with static analysis to have the best effect.
From: Issac Gouy
Cedric Beust wrote 'Who wants a refactoring IDE that "works most of the time"?'
Does method-rename refactoring in Java IDEs work when methods are invoked with the reflection API? Does it work across all those webservices XML config files?
(A method-rename refactoring that "works most of the time" is actually really useful.)
iirc "certain refactorings" is just two - method rename and safe method remove.
The strange thing about using type recovery from unit test runs to provide type information for refactoring - is that we could just do the refactoring and then see which unit tests fail.
On: Upcoming Gig: SEC
From: John Turner
Good to hear, Tim. I hope this means that you have convinced Sun to take part! Take it the next step: think about the performance measures that you want to tell the market about... this http://www.corefiling.com/insight/20060927-1200.html a few days ago responds to this http://blogs.sun.com/jonathan/entry/the_opacity_in_transparency from a couple of weeks back. Cheers. John.
From: Jeff Rose
Here's another idea... What if refactorings generated code which would wrap your current project AOP style. Then the next time you run a test or execute the program, whenever a refactored method was called it would hit the wrapper, check the type, and then decide whether to call the newly refactored name or use the old name because the type doesn't match the refactored class. Once the decision has been made it can get rid of itself both in the running code as well as in the back-end of the IDE.
Just a thought.
From: murphee (Werner Schuster)
How Dynamic Refactoring Works in Smalltalk (and Ruby?):
This also contains a long list of cases where all Java Refactoring tools fail, eg. components tied together with XML, scripted Java classes, uses of Reflection, JSP, etc etc. This means, that you'll still need high test coverage, otherwise you won't catch all the problems a simple rename brings. Mind you: in Ruby, many of these approaches are done in Ruby, instead of having to step outside the language (as in Java with XML and friends).
The Eclipse RDT (http://rubyeclipse.sourceforge.net/) guys have done work on Type Inference (sponsored by the Google Summer of Code):
They're busy adding that to one of the next releases.
From: Stefan Arentz
Issac: "Does method-rename refactoring in Java IDEs work when methods are invoked with the reflection API? Does it work across all those webservices XML config files?"
No of course not. Well, partly. When I rename a class in IntelliJ IDEA that is also referenced by name in a string literal or in some XML file it does actually know to refactor those too. That is something I do all the time. Not sure about method names but there will always be things that cannot be refactored because they are too obfscated in the code. But in case you are doing reflection stuff like that in your project then you probably also know that you should check those cases manually after refactoring someting that touches that code.
From: Jason Zaugg
A full suite of unit tests that achieve 100% code coverage may not yield useful information about call heirachy.
In unit tests that I write collaborators are mocked out in order to test the class in isolation. (This differs from the definition of unit test popularised by Rails)
Integration and Acceptance tests that test the interaction between classes would provide useful data.
From: Paul Morriss
It's working for me. Congratulations on getting comments up and running.
From: Benja Fallenstein
How about making the "n comments" thing on the front page a link? It doesn't matter much for fragments that have a "...", but for fragments that don't, it did take me a moment to figure out that I had to click on the title to read the comments.
Stefan Arentz wrote: "...there will always be things that cannot be refactored because they are too obfscated in the code."
Indeed, and that means we have Cedric Beust's 'refactoring IDE that "works most of the time"' - and it's actually really useful.
(It's still good to hear that IntelliJ continue to extend the scope of their refactorings.)
From: Nicola Larosa
I surely won't, I use Python, thank you very much. ;-P