t.Close can be Nil…

t.Close who close a TextInputStream instance can be Nil at run time. *

I’m starting to get that - surprisingly enough - after I boot on a newly installed El Capitan (on a totally free hard disk)… / Xojo 2015r1 (off line)

  • I think I read we can do that in the old forum.

Xojo 2015r1

dim t as TextInputStream = nil t.close

Well, as expected this code raises a nil object exception. So you can’t call close on a nil TextInputStream variable.

Thanks Christian.

I checked and found nothing in TextInputStream.Close / docs.

That is standard for any method call.

maybe this will work

dim t as TextInputStream = “”
t.close

Any object can be Nil.

[quote=227976:@Lennox Jacob]maybe this will work

dim t as TextInputStream = “”
t.close[/quote]
You’ll get a Type Mismatch compile error with this.

That would be due to a coding error. A previously created textinputstream cannot spontaneously become nil.

Tim:

I do not checked, yet. Thank you for the cue.

I will explorate.

So, at last, using t.CLose was a bad advice that I must forget.

Emile, why don’t you just check to see if the TextInputStream is nil before trying to close it?

if t <> nil then t.close

If I remember correctly, years ago Joe Strout advised to use only t = nil. Therefor I never use t.close; instead I use t = nil.
Is that advise still valid nowadays?

Have fun with Emile:

the code I used was:

t.Close t = Nil

And since t = Nil does not makes an error, I removed t.Close and keep t = Nil.

BTW: I do not even know if it is mandatory (since t = Nil is the last line of code there…)

Setting any object to Nil never raises an error. You can set any object to Nil at any time. Just don’t do anything with it afterwards or you’ll crash.

It should be exactly the other way around, you have to call t.Close and you can set t to Nil but don’t have to.

The two things have actually nothing to do with each other:

  • t.Close closes the TextInputStream, so the Xojo framework can properly close the file. This is important!
  • t = Nil sets the internal pointer to zero, which points to the TextInputStream instance, so the TextInputStream instance cannot be accessed anymore after this statement.

Note: it might be that setting t to Nil internally calls t.Close, but since it is not mentioned in the docs, I wouldn’t rely on it.

Let me add another thought to this. I would never, ever set an I/O object to nil; I would ALWAYS Close it. Here’s why (and keep in mind that the current operating systems may be smart enough to alleviate this)…

When you open a file, the OS creates structures that allow access to the file. Setting the I/O object to nil does not, generally, inform the OS that the structures should be flushed and destroyed. Thus, the OS may have data buffers unwritten to the file or to the structures. This isn’t usually a problem for files that are opened for READ ONLY but may interfere with multi-user access to files enabled for write access. In this case, data thought to be written to the file may not actually get flushed to the disk and might get lost. In the worst case, the OS fails to flush its data structures for the file and you could wind up with a corrupted disk allocation table. Hopefully, modern operating sytems can deal with this cleanly.

My recommendation is to always Close input and output files, rather than setting them to nil. The same for Databases and Recordsets. (I don’t trust the ‘closes when going out of scope’ approach, but that’s just my quirkiness.)

You can trust that this works on RecordSets, as the docs say:

But for TextInputStream and TextOutputStream there is no such remark in the docs, hence you need to use Close to properly close the file.

Then the docs should be updated, as you can definitely rely on the stream being closed.