I love a good, testy comment section in a blog post. The discussion in the comment section of my FreeAndNil post has been interesting and lively. In addition, the thread in non-technical continues apace, with new threads springing up! Along the way, a couple of interesting points were made that I’d like to highlight here because I think they are germane.
- First, I can sum up the article as follows: “Don’t use FreeAndNil. If you feel the need to use FreeAndNil, then your code almost certainly needs to be refactored to limit the scope of your references.”. People arguing for it’s use are, in my mind, simply saying “I don’t know how to or don’t care to control the scope of my pointers”
- Second, I want to stress again that I totally get that sometimes you have to use FreeAndNil. Sometimes you maintain old code that played fast and loose with pointer scope, and didn’t contain things like we now know you should. I get that. But those situations should cause you shame and embarrassment, and should motivate you to refactor your code to control references and make the need for FreeAndNil go away. The reason that I totally get this is that I manage such a codebase. The point isn’t about maintaining legacy code, it’s about how to write new code the right way. And if you are writing new code while feeling the need to FreeAndNil stuff, then you aren’t doing it right, quite frankly.
- Jolyon Smith wrote the following in the comments: “Surely you must also admonish everyone to write code that never requires the use of if Assigned(someReference) then…” Well, yes, I suppose that is exactly correct in most cases, unless you are doing lazy initialization, which I wouldn't recommend using anyway. If you are using Dependency Injection -- and you should be -- there is never a reason to be worried about your references not being assigned.
- John Jacobson writes: “Reference-counted interfaces are what you should be using anyway, keeping your actual class implementations private and hidden in the implementation section of their unit.” He’s absolutely correct. Ultimately, you should be coding against abstractions, not implementations. If you are doing that – and of course you should be in Delphi via reference-counted interfaces – then you shouldn’t be freeing anything other than local, non-volatile variables, and you should never need to FreeAndNil those.
By now many of you all are probably saying “This guy is a nut! Get over the FreeAndNil thing already!” Well, okay, I agree I’ve beaten this drum quite a bit. And I agree that I’m pretty much a nut. But I really think that it represents a critical point that we all need to understand in order to move forward: Code needs to be under control. Good development dictates that we limit the scope of references. And finally, out of control references are the cause of many, many bugs, and are the cause of 100% of access violations. The use of FreeAndNil is a blatant symptom of this problem.
Here’s the bottom line, and I’ll be blunt: If you are arguing in favor of using FreeAndNil, what I really hear you saying is “I learned to code in 1991 and haven’t learned a thing since.”
Okay, that’s a little harsh. I’ll put it a bit softer: Worrying about pointers and references is, well, an old-fashioned way of thinking. There are ways to code so that worrying about whether a pointer is valid or not is no longer something you have to worry about. This way of coding is more productive, cleaner, and more effective. It produces high-quality, testable code.
Doesn’t that sound enticing and intriguing? Why wouldn’t you want to learn more?