[Rd] RFC: getifexists() {was [Bug 16065] "exists" ...}

Hervé Pagès hpages at fredhutch.org
Fri Jan 9 20:56:50 CET 2015


Hi,

On 01/08/2015 07:02 AM, Martin Maechler wrote:
>
>> Adding an optional argument to get (and mget) like
>> val <- get(name, where, ..., value.if.not.found=NULL )   (*)
>
>> would be useful for many.  HOWEVER, it is possible that there could be
>> some confusion here: (*) can give a NULL because either x exists and
>> has value NULL, or because x doesn't exist.   If that matters, the user
>> would need to be careful about specifying a value.if.not.found that cannot
>> be confused with a valid value of x.
>
> Exactly -- well, of course: That problem { NULL can be the legit value of what you
> want to get() } was the only reason to have a 'value.if.not' argument at all.
>
> Note that this is not about a universal replacement of
> the  if(exists(..)) { .. get(..) } idiom,

FWIW, if(exists(..)) { x <- get(..) } is not safe because it's not
atomic. I've seen situations where exists() returns TRUE but then
get() fails to find the symbol (even if called immediately after
exists()).

After scratching my head for a while I found out that the symbol was
removed by some finalizer function defined somewhere (not on the 
environment exists() and gets() were looking at, of course). And
since garbage collection is triggered between the moment exists() sees
the symbol and get() tries to get it, the finalizer was executed and
the symbol removed.

After that, I started to systematically use x <- try(get(...)) instead
(which is atomic).

Cheers,
H.



More information about the R-devel mailing list