From rpeng at jhsph.edu  Thu Nov 15 13:48:18 2007
From: rpeng at jhsph.edu (Roger D. Peng)
Date: Thu, 15 Nov 2007 07:48:18 -0500
Subject: [Rd] isOpen on closed connections
In-Reply-To: <Pine.LNX.4.64.0711150714150.11152@gannet.stats.ox.ac.uk>
References: <473B0739.3090507@jhsph.edu> <m2hcjoksd6.fsf@userprimary.net>
	<Pine.LNX.4.64.0711150714150.11152@gannet.stats.ox.ac.uk>
Message-ID: <473C4012.3030909@jhsph.edu>

Upon further consideration, I realized there is a philosophical element 
here---if a connection is closed and hence does not exist, is it open?

The practical issue for me is that when you do something like

close(con)

the 'con' object is still lying around and is essentially undefined.  For 
example, if I do

close(con)
con <- "hello"

then it seems logical to me that 'isOpen' would return an error.  But it feels 
natural to me that a sequence like

close(con)
isOpen(con)  ## FALSE?

would not lead to an error.  Perhaps my expectations are not reasonable and I'd 
appreciate being corrected.

Given Brian's comment, one solution would be to allowing closing but not 
destroying connections at the R level (maybe via an option?), but that is a 
change in semantics and I'm not sure if this problem really comes up that much.

-roger

Prof Brian Ripley wrote:
> I think the confusion here is over close(): that closes *and destroys* a 
> connection, so it no longer exists.
> 
> isOpen applies to existing connections: you cannot close but not destroy 
> them at R level, but C code can (and does).  You will see it in use in 
> the utils package.
> 
> 
> On Wed, 14 Nov 2007, Seth Falcon wrote:
> 
>> "Roger D. Peng" <rpeng at jhsph.edu> writes:
>>
>>> As far as I can tell, 'isOpen' cannot return FALSE in the case when 
>>> 'rw = ""'.
>>> If the connection has already been closed by 'close' or some other 
>>> function,
>>> then isOpen will produce an error.  The problem is that when isOpen 
>>> calls
>>> 'getConnection', the connection cannot be found and 'getConnection' 
>>> produces an
>>> error.  The check to see if it is open is never actually done.
>>
>> I see this too with R-devel (r43376) {from Nov 6th}.
>>
>>    con = file("example1", "w")
>>    isOpen(con)
>>
>>    [1] TRUE
>>
>>    showConnections()
>>
>>      description class  mode text   isopen   can read can write
>>    3 "example1"  "file" "w"  "text" "opened" "no"     "yes"
>>
>>    close(con)
>>    isOpen(con)
>>
>>    Error in isOpen(con) : invalid connection
>>
>>    ## printing also fails
>>    con
>>    Error in summary.connection(x) : invalid connection
>>
>>> This came up in some code where I'm trying to clean up connections after
>>> successfully opening them.  The problem is that if I try to close a 
>>> connection
>>> that has already been closed, I get an error (because 'getConnection' 
>>> cannot
>>> find it).  But then there's no way for me to find out if a connection 
>>> has
>>> already been closed.  Perhaps there's another approach I should be 
>>> taking?  The
>>> context is basically,
>>>
>>> con <- file("foo", "w")
>>>
>>> tryCatch({
>>>     ## Do stuff that might fail
>>>     writeLines(stuff, con)
>>>     close(con)
>>>
>>>     file.copy("foo", "bar")
>>> }, finally = {
>>>     close(con)
>>> })
>>
>> This doesn't address isOpen, but why do you have the call to close
>> inside the tryCatch block?  Isn't the idea that finally will always be
>> run and so you can be reasonably sure that close gets called once?
>>
>> If your real world code is more complicated, perhaps you can make use
>> of a work around like:
>>
>> myIsOpen = function(con) tryCatch(isOpen(con), error=function(e) FALSE)
>>
>> You could do similar with myClose and "close" a connection as many
>> times as you'd like :-)
>>
>> + seth
>>
>>
> 

-- 
Roger D. Peng  |  http://www.biostat.jhsph.edu/~rpeng/



[Rd] isOpen on closed connections
Roger D. Peng