Posts

When in Rome, do as the Romans do - Part I

Image
While different OOP languages share some common principles and many coding patterns will be the same or at least fairly similar, there are also some significant differences that can make some commonly used patterns from one language quite unsuitable in another—and if used, such patterns can cause a lot of trouble. Photo: Gary Todd from Xinzheng, China, PDM-owner, via Wikimedia Commons, https://commons.wikimedia.org/wiki/File:Colosseum_(48412957912).jpg One such pattern can be found in their serialization approaches. In Java, object serialization is performed on fields. In Delphi, the convention is to serialize published properties. That is also the original purpose of the published visibility specifier. Delphi also supports defining custom properties in TPersistent descendants, via DefineProperties method. When it comes to what kind of properties Delphi can serialize out of the box, there are some limitations, so you cannot serialize records, arrays, or indexed properties, and

Combining const and out parameters

This is a continuation of a previous blog post, Are const parameters dangerous? Basically, adding an out parameter into the mix does not change anything that has been said in the previous post about using const parameters. But out parameters, with their own side-effects, create a specific situation that requires additional explanation. First, let's see how an out parameter works. An out parameter is a var parameter with a twist. Just like a var parameter passes the original variable as a reference (pointer), so does the out parameter, but out also tells the compiler that the original value can be discarded, since it is not for passing any input data to the procedure, and will be only used for passing the result out of the procedure. For managed types, the compiler will clear the original contents of the out parameter at the call site. procedure OutInt(out p: integer); begin p := 5; end; procedure OutString(out p: string); begin p := '5'; end; procedure T

Delphi Event-based and Asynchronous Programming Webinar Replay

Image
"Embarcadero Technologies - Conversation with Dalija Prasnikar, Embarcadero MVP, on covering her new book on Delphi Event-based and Asynchronous Programming."  Book intro by Neven Prasnikar Jr. and a recording of live Q&A chat hosted by Jim McKeeth and Stephen Ball.  https://www.youtube.com/watch?v=C8clqgydTsM Making this webinar has been quite eventful    The whole experience can be best summarized with: The year is 2021. After a whole year of lockdowns and working from home, cameras have decided they have had enough of it. Mics didn't join the rebellion  Thank you all for joining live session and watching!

Overprotecting multithreaded code

Running long tasks in a background thread to keep the UI responsive is one of the main purposes of multithreading. A common code pattern for doing so would look like: procedure TMainForm.BtnClick(Sender: TObject); begin TThread.CreateAnonymousThread( procedure begin DoSomeWork; end; end).Start; end; However, such code often needs to show the results of that long work to the user. Working with the GUI from a background thread is not thread-safe, so such code should be executed in the context of the main thread: procedure TMainForm.BtnClick(Sender: TObject); begin TThread.CreateAnonymousThread( procedure begin DoSomeWork; TThread.Synchronize(nil, procedure begin ShowResults; end); end; end).Start; end; Because ShowResults will run in the context of the main thread, the code in ShowResults should be as minimal as possible—read: as fast as possible. Once you enter into the Synchronize (or Que

Autorelease Pool

Manual memory management requires some thought and ceremony. It is not so much of a problem with long-lasting instances, but managing temporary local objects, especially when you need to create more than one, is a tedious job. It also hurts code readability. While Delphi allows automatic memory management for classes that implement interfaces, using ARC is not always feasible. If you have to deal with preexisting classes that don't support ARC, you will have to deal with manual memory management. Reference counting also adds some overhead, and using reference counting in your own classes is not always a viable approach. When performance is not paramount, simpler and cleaner code without try...finally blocks would be nice to have. Life always finds a way and various ARC-based smart pointer and similar lifetime management wrapper implementations have started to appear in the wild. One common place where constructing many object instances can be found is unit testing. While lifeti

Delphi Event-based and Asynchronous Programming Book - Paperback Edition and Invitation to Webinar

Image
 You asked for it, and here it is!  The paperback version of the book is here! (I hope Gaia will forgive me again...) Celebrating the release of the new book, “Delphi Event-based and Asynchronous Programming,” Jim McKeeth and I will have a chat about it during a webinar featuring a Q&A where I'll be answering your questions. Let's not reinvent the wheel here... here's the intro Jim McKeeth wrote: Join Embarcadero MVP Dalija Prasnikar and Jim McKeeth for this fireside chat about Event-Based and Asynchronous Programming in Delphi. This is your chance to get answers to your questions on the topic. Register for the webinar here: https://register.gotowebinar.com/register/9060745883744641039 Learn even more from Dalija’s recently published 291-page book: “Delphi Event-based and Asynchronous Programming,” and score a 50% discount on the physical book if you purchase the ebook!  If you have already purchased the eBook version, and wish to buy the paperback, you're also elig

If it is too complex, you are probably doing it wrong

If there is one thing experience has taught me, it is that too much complexity in some code usually means that design is wrong. That does not mean that everything must and can be as simple as 2 + 2, but complexity should sound some inner alarm and should make you reconsider your approach. If basic concept, without all convenience features is hard to follow then it is most certainly wrong. Adding convenience features can bring some additional layers of complexity and certainly plenty of code, but they don't usually pose a significant problem if basic concept is done right. There are many practices, patterns and advices going around that should help writing clean and maintainable code, but two stand before all else. Violate them and you will be in trouble, sooner or later (usually sooner or in the worst possible moment). KISS - Keep it simple stupid -  https://en.wikipedia.org/wiki/KISS_principle YAGNI - You aren't gonna need it -  https://en.wikipedia.org/wiki/You_aren't_gon