Why EndOfLine.UNIX on one condition and just EndOfLine on the other?
Bad edit That was copied from the Windows target code and the data is being written to a Linux server task where EOL type matters, but my mind was in Unix-land when I edited the original, so left that off.
Out of curiosity, why do you have the line
TOS.Flush
since the Close statement will force a Flush anyway? Typically, Flush is used to write out the contents of the file buffer while keeping the file open.
It’s an old habit and related to the old versions of Xojo (this code is being brought forward from an original REAL.Studio project from 2007r3.
I’m not sure to see the difference between the code above and the code below :
If f <> Nil And Not f.Exists Then
Try
theTOS = TextOutputStream.Create(f)
If defaultEntry <> "" Then
theTOS.Write defaultEntry + EndOfLine.UNIX
Else
theTOS.Write "" + EndOfLine
End If
theTOS.Flush
Catch e As IOException
// Permissions issue?
End Try
If theTOS <> Nil Then
theTOS.Close
End If
End If
In both case theTOS.Close will be done if not Nil ?! (yes I read the documentation about Finally).
In this particular case, they are equivalent.
The nuance with Finally is that it will be executed regardless of whether you caught the exception or not. Consider this case
var t as TextOutputStream
try
t.write("x")
catch e as IOException
MsgBox("caught an exception")
end try
MsgBox("did we get here?")
In this case, we will get a NilObjectException, which will not be caught. The MsgBox after the try/catch will never be excecuted, because the uncaught exception will immediately exit the method and propagate up the call stack. As opposed to
var t as TextOutputStream
try
t.write("x")
catch e as IOException
MsgBox("caught an exception")
finally
MsgBox("finalizing")
end try
MsgBox("did we get here?")
Now we will get the “finalizing” MsgBox, but not “did we get here?” You use Finally to clean up in the case where some completely unexpected and/or unrecoverable exception occurs.
That will still crash if you get an IOException because then theTOS is nil, hence “theTOS.Close” will cause a NOE. There are two solutions to this:
- Check for theTOS <> nil
- add a “return” inside every “catch” clause because the finally code won’t be called if the function issues a “return” statement.
In this example you do not need “Finally” unless the code in the try can raise exceptions other than the ones you catch - which is probably not the case here.
Finally is needed when you call code that you are not sure about which exceptions it may raise, and if you do not want to add a catch-all with catch e as RuntimeException
. In this case, if the deeper code raises an exc that you do not catch, you may still want to clean up, such as delete a just-created file, before code higher up in the calling chain will catch the exception and handle it gracefully - but since that higher code does not know you created a file, you need to do that in your local finally handler.
However, remember that, in order for the finally code to be called, you must not leave the function through a return
statement!
Thank you Tim and Thomas, that’s more clear for me. I was interested in the Finally instruction because I may code better the way I read my Preferences files.
In all my programs, I read prefs file at startup to get folderitem, make Arrays, Dates and so on. Of course I try to avoid problem even if the guy edit the PrefFile in TextEdit, but problem may still occur. The file may be corrupted etc.
Then I read the file in a string and I do the job in a Method like :
If MyPrefFil.Exists Then
Read PrefTextFile and set variables
MyFolderItem = Read…
MyArray = Read…
MyDate = Read…
Else
MyFolderItem = Default…
MyArray = Default…
MyDate = Default…
End If
Exception TypErr
System.Beep
MyFolderItem = Default…
MyArray = Default…
MyDate = Default…
I have two times the same code. I thought about put a Goto: Exception in the Else but I’m not sure it’s a good thing.
When I read this topic and learn Finally instruction exists, I said to myself that maybe there is a good way to do with this.
I’ve been using two Modules for at least 10 years to save preference files for both mac and win that does everything you are trying to do. XMLPreferences written by Joseph Sharp, (E-mail: joesharp@mac.com), and another called XMLdictionary 1.2.6 by Kevin Ballard, (kevin@sb.org http://www.tildesoft.com) that does everything you are trying to accomplish with your preferences code. I think the only thing I have ever had to modify was eliminating code for Mac Type that was no longer valid.
Syntax is similar for most variable types. Here is what is used for a string:
somevariable As String = GetPrefString(("SomeKeyName", "Default Value")
Saving is like this
SetPrefString(("SomeKeyName", somevariable)
I’m not sure how hard irt would be to find this any more, but if you PM Me I’ll send it to you to look at.
Nope. It was a response to Thomas Robisson about him reading his preference files. There might be a better way to do what he is doing that he might want to take a look at despite the fact that the thread is about Try, Catch Finally and Thomas isn’t the OP.
A better way to avoid thread confusion is quoting part of what you intend to talk aside instead of being on topic.
Like:
I’ve been using two Modules for…
Thank you, I heard about module for pref but I don’t want to rewrite all.
My question was, asked differently is : As there is a way to use Finally in a Try Catch , is there a way to use Finally with Exception ? It seems not.
What you’re doing here:
Could be translated to a modern Try/Catch like:
Try
If MyPrefFil.Exists Then
Read PrefTextFile and set variables
MyFolderItem = Read…
MyArray = Read…
MyDate = Read…
Else
MyFolderItem = Default…
MyArray = Default…
MyDate = Default…
End If
Catch err
System.Beep
MyFolderItem = Default…
MyArray = Default…
MyDate = Default…
Finally
// whatever
End