Skip to content

isOpen on closed connections

6 messages · Roger D. Peng, Seth Falcon, Brian Ripley +2 more

#
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.

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)
})

So the problem is that if the block in the 'tryCatch' succeeds, the 'finally' 
will produce an error.

I'm not exactly sure of what I'd want since it seems modifying 'getConnection' 
would not be a great idea as it is used elsewhere.

-roger
#
"Roger D. Peng" <rpeng at jhsph.edu> writes:
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 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
#
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:

            

  
    
#
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'd support a change, to having a closed-but-not-invalid status for a
'rw' connection, and to have a usable 'isOpen'. The suggestion of
relying on user-code to always "housekeep" after calling 'close', eg by
setting to NULL, seems a bit risky as a guideline for R as a whole (one
can never tell what convention a different author's code might follow).
And the 'myOpen' solution will work (I'm about to use it myself) but
cumbersome if everyone has to do it. With things as they are, I can
foresee a stream of "why does.../RTFM" emails...

Perhaps the more fundamental issue is whether 'getConnection' should
actually throw an error. 
I'm getting bitten by this in R 2.6.1-- I use 'getConnection' in an
'on.exit' statement (where I can't be sure of the state of the
connection), and it's throwing an error instead of returning NULL as it
used to (and as the documentation still states).