gabr wrote a post yesterday titled When changing semantics, make sure that existing code will break: basically another post about leaning on the compiler. It reminded me of a trick I often use in Delphi, which I thought I’d pass along.
Delphi’s refactorings don’t work. At least, not for us. Delphi’s refactorings only seem to pay attention to files that have been explicitly added to the project, which in our case is about six out of thousands. We don’t add every single file to the project, because we have thirty-something different projects that share a great deal of code, and it would be impractical for us to manually keep track of which projects use which files. The compiler can keep track of it for us just fine. The IDE’s refactoring tools, of course, don’t actually use the compiler, so they’re busted.
(Yes, we should use packages. It’s not feasible at the moment, for historical reasons that we are gradually eliminating. But I digress.)
Delphi’s Find References doesn’t do squat for us. So when I must find references, and a grep isn’t good enough (because the method name is too common of a word), I like to do a “poor man’s Find References”. There are two variations on the theme:
Rename the method. If it’s called
Foo, rename it to
Foo2. Consider making the new name something that will be unique enough to grep on.
Add an extra parameter. I like to add a parameter at the end called
X: Boolean. This one is handy if you’re planning to change the parameter list anyway, and are doing a Find References to see where all you’d have to change.
Once you’ve made the change, then you start making everything compile. Everyplace the compile breaks, you change to call the new method signature. Once you can build everything with no errors, your Find References is done.
If you did all this on a clean checkout, then all you need to do to see your Find References is to view the diffs (if you’re using Subversion, then you probably want either TortoiseSVN > Show Modifications or Tools > Svn Modifications). Or, if you chose the “rename” path, then hopefully the new name is unique, and you can grep for it.
Then you probably revert all of those messy changes you just made. But (hopefully) you learned what you set out to learn.
In occasional cases, Poor Man’s Find References is actually better than a working IDE Find References would be. The fact that you actually touch every call site can make it easier to do viral reference searching, i.e. tracing it back multiple levels where you need to. A standard Find References doesn’t give you a good way to branch out — e.g., you can’t say “okay, take these three places it’s used, and find references to all of them now”. A standard Find References is one search at a time; no branching, no backtracking to continue an earlier search. But a Poor Man’s Find References gives you all the depth (and backtracking) you need.
(Mind you, most of the time I’d rather have an IDE that can actually do a Find References.)