Tuesday, June 5, 2007

Ruby Screenshot of the Week #13: Refactoring

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


As of this evening there are two new features in the builds: Find Usages, and Rename. Let's start with Find Usages. Right click on a symbol and choose "Find Usages" (or use the keyboard shortcut). Let's say I search for the usages of the UserMail class in the Mephisto Rails blogging application (click for full size):








This feature also knows about .rhtml and .erb files - it parses the embedded Ruby and analyzes it. Here's an example where I've searched for the usages of a @comments field in a controller - notice the .rhtml matches:






(Sorry, I know these images might be a bit large on some screens; I should have taken the screenshots at a smaller screen resolution than my usual 1680x1050.)



In the Find usages dialog I can also ask NetBeans to find subtypes of the class rather than usages. Here's an example of what I get if I search for subclasses of the ApplicationController class:






Next, Rename refactoring. Let's say that I want to rename the @comments field in my Rails application controller. I right click on it, choose a new name and hit OK. I then click "Preview", and in the bottom window I get a list of refactoring operations, along with diffs for the currently selected item. I can (and should!) walk through the changes with the Up/Down arrows, and I can unselect any changes that I don't like before I click the Refactor button to apply the changes. Click on the image for full size (I'm showing both the dialog and the results window here; in reality you'd first get the dialog, and when you hit Preview it disappears and you see the bottom window.)








Again, notice how the renaming operation includes changes in .rhtml files. The advantage of this approach over a regular Search/Replace editor operation is that by using parse trees, we have a lot more confidence in the matches. The IDE will not confuse a local variable reference to foo with a method named foo. It does however still have difficulties knowing whether symbols and method names that occur in multiple places refer to say the same method, so at this point it errs on the side of optimism and presents them all as potential uses.



WARNING: This feature is definitely preliminary!! Hopefully the bold red warning in both the Rename and Find Usages dialog makes this really clear. The Refactor button will be disabled and Preview required shortly.



However, this feature should be improving rapidly as I get feedback and implement some more things on my todo-list. Find Usages at least should be quite useful as a navigation tool. If you're going to use the Rename feature, please make a backup of your code first!



(This feature requires the very latest builds - try the Ruby IDE from nbextras.org, or for fuller instructions, see the wiki page. Auto updating from M9 isn't working any more because I'm relying on private APIs that have changed incompatibly.)



P.S. A great big thank you to all of you who have tried the NetBeans Ruby support, and especially to those of you who have provided feedback!


28 comments:

  1. Looks good. A big thanks.

    ReplyDelete
  2. Dushyanth TiwariJune 5, 2007 at 11:31 PM

    Just curious. Would appreciate an honest reply.
    Are you adding rails support to Netbeans to make rails development better?
    Or to make more rails developers use Netbeans?

    ReplyDelete
  3. Ruby 'find usages' is a killer app. Good luck!

    ReplyDelete
  4. Hi Tor - can I ask for a quick update re how the installation support for setting up the equivalent TextMate shortcuts/bundle support is going? Last I heard there were still some work to be done to get this occurring properly through the update mechanism?
    Refactoring support is looking great...looking forward to having some time to test/play. Cheers GregH

    ReplyDelete
  5. Nice walk through. I went ahead and tagged it under ruby on tektag.com for future reference.

    ReplyDelete
  6. Hi, Tor! Excellent (as usual) work! one question - is it possible to change the font-size of a help window (which appears during autocompletion with samples of the ruby code inside) ?

    ReplyDelete
  7. @Dushyanth: I would believe the response is both. Why would you need an 'or' ?

    ReplyDelete
  8. Tor, could you please teach NetBeans DRYML for Hobo: http://hobocentral.net/ ?
    They've already got some TextMate support and looks like someone may be working on RadRails. It would definitely be good to have.

    ReplyDelete
  9. Nice work. Netbeans is shaping up to be a very good Ruby development environment

    ReplyDelete
  10. Yes, that may be possible. If you look at the forums on the HoboCentral site you'll see a lot of the footwork already done. For example, you can see how they're doing it for TextMate right here:
    http://hobocentral.net/forum/viewtopic.php?t=2328



    Perhaps downloading Niko's bundle from subversion will give you all that's needed to have it going in just a few minutes?

    ReplyDelete
  11. Hi JohnH, give build #1830 a shot (http://deadlock.nbextras.org/hudson/job/ruby). DRYML files now get RHTML treatment. TODO - handle the non-html tags (like <:attribute> tags) better and improve completion etc.

    ReplyDelete
  12. Tor, I've got a question about an older feature. I'm trying to import TextMate bundles using the nbm you built. I imported it, and when I go to Edit | Source | Show Templates | Import, I see the .tmbundle file type option, but when I try to import a .tmbundle file I get XML parsing errors: 'Content is not allowed in prolog', etc. It seems like it's trying to parse it as xml. I'm using the lastest ruby only mac os net beans zip.
    Steve

    ReplyDelete
  13. Stephen, the importer imports two kinds of abbreviations: NetBeans abbreviation files (XML) and TextMate bundle files (.tmbundle). It sounds like it's trying to import something as a NetBeans abbreviation file. Can you make sure that you've changed the filetype filter in the filechooser to the TM bundle type, and you have chosen the "whatever.tmbundle" file as the file to be imported? (If you choose any other file, like as specific snippet file, it's probably not doing the right thing).

    ReplyDelete
  14. Yeah, I'm selecting 'TextMate Bundles (*.tmbundle) as the File Format, and I tried importing my local Ruby.tmbundle and Rails.tmbundle, among others, with no luck. Here's a sample of the errors message I get importing Ruby.tmbundle:
    IMPORT SUMMARY
    ------------------------------
    Parsing error in "#!;usr;local;bin;ruby -w.plist"; skipping
    Content is not allowed in prolog.Parsing error in "010 ruby for element in collection.plist"; skipping
    Content is not allowed in prolog.Parsing error in "020 ruby inject.plist"; skipping
    Content is not allowed in prolog.Parsing error in "040 ruby reject.plist"; skipping

    ReplyDelete
  15. Interesting. It sounds like your snippet files have a different format than the once I had and made work. Would you mind zipping up your .tmbundle directory and mailing it to me? tor.norbye@sun.com

    ReplyDelete
  16. Hi Tor! I cannot find "soft word wrapping possibility"- is it in NetBeans? JEdit has good one - when it wraps strings, then each wrapped string begins from the indention that "parent" string has. It would just great to has such in NetBeans

    ReplyDelete
  17. Tor, since version 1849 code templates don't work, what can it be?

    ReplyDelete
  18. "This feature also knows about .rhtml and .erb files - it parses the embedded Ruby and analyzes it. "
    Does it know about .mab files? :)

    ReplyDelete
  19. Hi Jerrett,
    Yes, it knows about .mab files; these are treated as Ruby files (which they are, as far as I can understand). Thus, "normal" code completion (and go to declaration, and indentation, and bracket matching etc. etc.) should just work. One area we could improve in though is to teach code completion about the context the .mab file will be executed in, such that the inherited methods ("html", "p", etc.) show up in code completion. That's not done. If you know (or know where I can find) information on what modules or classes are included in the context when a .mab file is running that would help. I recently did something similar for .builder files (teaching code completion what the "xml" object refers to) and .rjs files (for the "page" object).

    ReplyDelete
  20. Tor,
    I would like to thank you for your work - great stuff. I have been seeing netbeans+rails buzz on the web and today I finally gave it a shot. I would have to say that so far everything just works!
    I started out witht the full boat netbeans download (160+ MB) and then went with your ide only build - I hope this is an option when this gets released
    thanks again!

    ReplyDelete
  21. Now code templates work again, thank. Another tip - if there is a lot of migration in the project, than all of them cannot be located on the screen, so it's impossible to select (or scroll) the latest migrations (at least on my 12800x800 screen i can see only 40 of them)

    ReplyDelete
  22. I still can't get importing of TextMate bundles to work. I downloaded build 1951, running on Mac OS X.

    ReplyDelete
  23. Tor, great stuff, I just picked up the latest build with rails plugin support....fantastic!
    Sorry if this is the wrong place/process ... but what are the chances that support for "script/console" will be implemented?
    thanks again..

    ReplyDelete
  24. Tor,
    Thanks for figuring out the binary plist problem. I guess I could have figured that out. Thanks for the incredibly quick responses! This Ruby NetBeans thing is really shaping up. Keep up the fantastic work!
    Steve

    ReplyDelete
  25. This is very cool and very promising! Excellent! You are worthy of your namesake ;)

    ReplyDelete
  26. Hey Tor, thanks for that. DRYML is, to me, one of the most exciting things for Rails that I've seen in a long time. It looks like they've got a lot in store for Hobo as time goes forward so this is definitely a positive move!

    ReplyDelete
  27. "It does however still have difficulties knowing whether symbols and method names that occur in multiple places refer to say the same method, "
    You say that like it's a small detail, but isn't that really the hard part of the Ruby refactoring problem?

    ReplyDelete
  28. Just picked up build 1952 with Rails Console support! Thanks. I would just like to say that I have switched to Netbeans for my dev work and have been very pleased. I would encourage anyone who hasn't yet found their Nirvana in a Rails/Ruby IDE to give Netbeans a try.

    ReplyDelete