I find that my methods have become shorter over time, regardless of the language or editor I'm using (I currently use vi a lot, with stints in Together/J (talk about ends of the scale)). In my opinion, the editor is no "excuse" for not factoring code properly. I used to believe in a lot of commenting, but have changed that opinion significantly over the last few years (though I still believe in commenting public interfaces and classes). Fowler's /Refactoring/ book convinced me that I was on the right path. I loved his observation/recommendation, that if you feel the need to put in a comment, perhaps you should be feeling instead the need to factor the bit of code you're commenting into a separate method, and then call it. Give the method a name similar to the comment you were going to write. As you've demonstrated, appropriately named methods really are self-documenting, and if you keep them small and tight, you don't need comments nearly as often. --- Ron Jeffries <ronjeffries / REMOVEacm.org> wrote: > I noticed in some code that Chet and I were writing that, as > Smalltalkers, we tend to write really > tiny methods. Here's a patch of code to show what I mean. Pay no > attention to what it does, just > look at how it looks. > > def filesUnderManagement > names = (Dir.entries(@directoryName).select { | each | ! (/.bak/ > =~ each) }).sort > names.reject { |each| FileTest.directory?(sourceName(each)) } > end > > def archiveFiles > Dir.entries(@directoryName + '/archive').reject { | each | /^\./ > =~ each }.sort.reverse > end > > def backup > timeString = Time.now.strftime("%Y%m%d%H%M%S") > filesUnderManagement.each { | each | backupFile(each, > timeString)} > end > > def backupFile (fileName, timeString) > File.syscopy(sourceName(fileName), > archiveName("#{fileName}.#{timeString}")) > end > > def sourceName(fileName) > @directoryName + '/' + fileName > end > > def archiveName(fileName) > @directoryName + '/archive/' + fileName > end > > def restore (timeString) > restoreFiles(filesToRestore(timeString)) > end > > def restoreFiles(fileList) > fileList.each { | each | restoreFile(each) } > end > > def restoreFile(fileName) > short = shortName(fileName) > File.syscopy(archiveName(fileName), sourceName(short)) > end > > def shortName(fileName) > pattern.match(fileName)[1] > end > > def timeStamp(fileName) > pattern.match(fileName)[2] > end > > def pattern > /(.*)\.(.*)/ > end > > In this whole program, a code manager we're working on, the longest > method is this: > > def findFirstOccurences(names) > current = '' > firstOccurrences = [] > names.each do | each | > short = shortName(each) > if (short != current) > current = short > firstOccurrences << each > end > end > firstOccurrences > end > > That's 12 lines long and to me it is way too long. > > I see very little Ruby code where the average method length is just a > couple of lines. I suspect > it's because it's so hard to find methods in a source file that we > instinctively have as few as > possible. Clearly there are techniques one could use to make things > better: we could alphabetize the > methods or arrange them in other ways. But the problem remains. > > I think that part of the power of Smalltalk comes from the fact that > the methods are all separate. A > Smalltalk browser has a pane listing just the method names, typically > alphabetically (or possibly > grouped, alpha inside each group). When you click on a method in the > list pane, that method appears. > You can look at it, edit it, save it, look at another, and so on. > > At first when you use Smalltalk, it seems choppy as you have to keep > clicking around to see what's > going on, and in a text window you can sort of do that with your > eyes. But take a look at these > methods from the program we're writing. I'm not claiming that the > names are perfect yet -- this is a > work in progress. But read my pretend throughts below and see if you > can get what I /like/ about > tiny methods: > > def restore (timeString) > restoreFiles(filesToRestore(timeString)) > end > > hmm, OK, he does a restore by restoring all the files to restore, > based on the time string. I wonder > how he restores a file ... > > def restoreFiles(fileList) > fileList.each { | each | restoreFile(each) } > end > > OK, he goes through them all and restores each one ... how does he do > that? > > def restoreFile(fileName) > short = shortName(fileName) > File.syscopy(archiveName(fileName), sourceName(short)) > end > > Oh, I see, he is copying the archived file back to the source file. > (You have to know here that we are saving the Ruby file abc.rb as > abc.rb.20020110164900 in our code > manager: we've appended a time stamp to the file name. That's not > clear here. It should be.) > > I wonder how he decides which file to restore ... > > def filesToRestore(timeString) > findFirstOccurences(olderFiles(timeString)) > end > > OK, he takes the first occurrence of the files older than the time > string .. > > def olderFiles(timeString) > archiveFiles.select { |each | timeStamp(each) < timeString } > end > > And so on. > > Now most of us who read larger methods are used to doing the reverse. > We look at a big blob of code > and figure out little chunks of it. Then maybe we comment the code or > make a note or just leave the > figuring out to the next person. > > Tiny methods -- when you get used to them -- are IME /much/ easier to > write and to work with. > > Editor-based languages like Ruby, Java, C++, encourage longer methods > because we have to search with > our eyes to figure things out. > > What does this mean? I don't know. I think it might mean that a > browser for Ruby or Java or C++ > would be really good. Visual Age for Java is really wonderful in the > hands of people who learn to > work in the browser mode. > > Or maybe ... it doesn't mean anything. The comments here will perhaps > tell me. > > Ronald E Jeffries > http://www.XProgramming.com > http://www.objectmentor.com > I'm giving the best advice I have. You get to decide whether it's > true for you. ===== --------------------- Mike Thomas http://www.samoht.com It's better backwards --------------------- __________________________________________________ Do You Yahoo!? Send FREE video emails in Yahoo! Mail! http://promo.yahoo.com/videomail/