Finally: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Finally
| Old | New | Line | |
|---|---|---|---|
| 1 | + | Back to [[Reserved words]]. | |
| 2 | + | ||
| 3 | + | The reserved word `finally` identifies a [[Block|block]] of code that should always be processed, regardless of whether the preceding `try` block was fully executed or has been exited early (in case of an [[Exception]], [[Exit]], [[Break]] or [[Continue]]). | |
| 4 | + | ||
| 5 | + | ## Examples | |
| 6 | + | ||
| 7 | + | Simple example: | |
| 8 | + | ||
| 9 | + | ``` pascal | |
| 10 | + | begin | |
| 11 | + | ... | |
| 12 | + | try | |
| 13 | + | ... // code to check | |
| 14 | + | finally | |
| 15 | + | ... // code which should always be executed even if try exits early | |
| 16 | + | end; | |
| 17 | + | ... | |
| 18 | + | end; | |
| 19 | + | ``` | |
| 20 | + | ||
| 21 | + | Example with error handling: | |
| 22 | + | ||
| 23 | + | ``` pascal | |
| 24 | + | begin | |
| 25 | + | ... | |
| 26 | + | try | |
| 27 | + | try | |
| 28 | + | ... // code to check | |
| 29 | + | except | |
| 30 | + | ... // error handling | |
| 31 | + | end; | |
| 32 | + | finally | |
| 33 | + | ... // code which should always be executed even if try exits early | |
| 34 | + | end; | |
| 35 | + | ... | |
| 36 | + | end; | |
| 37 | + | ``` | |
| 38 | + | ||
| 39 | + | ## Non-Exception Code | |
| 40 | + | ||
| 41 | + | Despite the name, Try-Finally is not strictly tied to the usage of exceptions, and also provides benefits in code where no exceptions can be raised. The reason for this is that the Finally block will always be executed, even if the try block exits early. | |
| 42 | + | ||
| 43 | + | This can be very useful e.g. for the [[Break Fast Break Even]] paradigm, where [[Exit]] or other jumps (such as [[Break]] or [[Continue]]) are used: | |
| 44 | + | ||
| 45 | + | ``` pascal | |
| 46 | + | function CheckFormat(const CSVString: String): Boolean; | |
| 47 | + | var | |
| 48 | + | sl: TStringList; | |
| 49 | + | begin | |
| 50 | + | Result := False; | |
| 51 | + | sl := TStringList.Create; | |
| 52 | + | try | |
| 53 | + | sl.Delimiter := ';'; | |
| 54 | + | sl.StrictDelimiter := True; | |
| 55 | + | sl.DelimitedText := CSVString; | |
| 56 | + | ||
| 57 | + | if sl.Count <> RowCount then | |
| 58 | + | Exit; // Will automatically execute the finally block before exiting | |
| 59 | + | // Check field data, e.g. | |
| 60 | + | if not isNumber(sl[1]) then | |
| 61 | + | Exit; // Will automatically execute the finally block before exiting | |
| 62 | + | // ... | |
| 63 | + | finally | |
| 64 | + | sl.Free; | |
| 65 | + | end; | |
| 66 | + | // All checks passed | |
| 67 | + | Result := True; | |
| 68 | + | end; | |
| 69 | + | ``` | |
| 70 | + | ||
| 71 | + | Because of the try-finally, the code can simply call exit, and the finally block ensures that sl will be freed afterwards. Without the try-finally, each of these blocks would require a seperate sl.Free call: | |
| 72 | + | ||
| 73 | + | ``` pascal | |
| 74 | + | function CheckFormat(const CSVString: String): Boolean; | |
| 75 | + | var | |
| 76 | + | sl: TStringList; | |
| 77 | + | begin | |
| 78 | + | Result := False; | |
| 79 | + | sl := TStringList.Create; | |
| 80 | + | sl.Delimiter := ';'; | |
| 81 | + | sl.StrictDelimiter := True; | |
| 82 | + | sl.DelimitedText := CSVString; | |
| 83 | + | ||
| 84 | + | if sl.Count <> RowCount then | |
| 85 | + | begin | |
| 86 | + | sl.Free; | |
| 87 | + | Exit; | |
| 88 | + | end; | |
| 89 | + | ||
| 90 | + | if not isNumber(sl[1]) then | |
| 91 | + | begin | |
| 92 | + | sl.Free; | |
| 93 | + | Exit; | |
| 94 | + | end; | |
| 95 | + | ||
| 96 | + | // ... | |
| 97 | + | ||
| 98 | + | sl.Free; | |
| 99 | + | end; | |
| 100 | + | ``` | |
| 101 | + | ||
| 102 | + | Therefore try-finally can even in code without exceptions, help to ensure that the cleanup is performed, without having to consider each exit point individually | |
| 103 | + | ||
| 104 | + | ## Caveats | |
| 105 | + | ||
| 106 | + | The `finally` part is *not* executed if a [`halt`](https://www.freepascal.org/docs-html/rtl/system/halt.html) occurred. | |
| 107 | + | ||
| 108 | + | ## See also | |
| 109 | + | ||
| 110 | + | - [[Try]] | |
| 111 | + | - [[Except]] | |
| 112 | + | - [[Avoiding implicit try finally section]] | |
| 113 | + | ||
| 114 | + | --- | |
| 115 | + | *From the Free Pascal wiki, page "Finally", as it stood on 2023-08-14 after a change by Alextpp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
