The problem in this example is (plausibly) that the argument evaluation code in method selection itself uses an internal C-level version of try(), overriding the user's setting.

If this is the bug, I'll have to defer to more expert advice on whether, and if so how, the code can adjust for the current exception handling. (There don't seem to be many uses of this R_try() mechanism.)


On 7/21/10 2:36 AM, Sklyar, Oleg (London) wrote:
Hi all:

we have noticed for quite a while that certain errors cannot be handled
by R try, tryCatch etc blocks, but it was fairly difficult to understand
what were the conditions for this incorrect behaviour. Finally I stabbed
across a very understandable case, which is outlined in the (runnable)
example below.

The main message is: wrapping an S4 method call in a try block will not
help if an error occurs in evaluating an argument to such a call; this
works just fine for function calls (as opposed to S4 methods)

The particular example is a result of trying to write a unit test for a
constructor of a class object which should fail under certain
conditions. This failure obviously need to be caught for the unit test
to proceed. However, it is a general problem with handling some
exceptions in R.

# Consider a simple class MyClassA, which is derived from numeric and
for which
# we define a constructor (in form of a method). On its own this class
works nicely
# and so does exception handling of it:

setClass("MyClassA",
     contains = "numeric",
     validity = function(object)
     {
         stopifnot(object[1] == object[2])
         TRUE
     }
)


setGeneric("MyClassA", function(x) standardGeneric("MyClassA"))

setMethod("MyClassA",
     signature(x = "numeric"),
     function(x)
     {
         new("MyClassA", x)
     }
)

## OK
er = try({ MyClassA(c(1,2)) })

## OK (error in constructor)
er = try({ MyClassA(c(1,2)) })

## OK (error evaluating argument to a function)
er = try({ sin(MyClassA(c(1,2))) })


# Now consider we define MyClassB that has MyClassA in a slot
# and we define a constructor that takes such objects:


setClassUnion("MyClassAOrNULL", c("MyClassA", "NULL"))

setClass("MyClassB",
     representation(
         ca = "MyClassAOrNULL"
     ),
     prototype(ca = NULL)
)

setGeneric("MyClassB", function(x) standardGeneric("MyClassB"))

setMethod("MyClassB",
     signature(x = "MyClassA"),
     function(x)
     {
         new("MyClassB", ca = x)
     }
)

## OK
b = MyClassB(MyClassA(c(1,1)))

## FAILS (error evaluating argument to a method)
er = try({ MyClassB(MyClassA(c(1,2))) })

# As you see the last error cannot be handled


# Moreover. If we define a function and a method as function(x) x then
# the function can be handled by try, yet the method cannot:

f = function(x) x

setGeneric("g", function(x) standardGeneric("g"))
setMethod("g", "MyClassA", function(x) x)

## OK (error evaluating argument to a function)
er = try({ f(MyClassA(c(1,2))) })

## FAILS (error evaluating argument to a method)
er = try({ g(MyClassA(c(1,2))) })



sessionInfo()
R version 2.11.0 Patched (2010-05-05 r51914)
x86_64-unknown-linux-gnu

locale:
  [1] LC_CTYPE=en_GB       LC_NUMERIC=C         LC_TIME=en_GB
LC_COLLATE=en_GB
  [5] LC_MONETARY=C        LC_MESSAGES=en_GB    LC_PAPER=en_GB
LC_NAME=C
  [9] LC_ADDRESS=C         LC_TELEPHONE=C       LC_MEASUREMENT=en_GB
LC_IDENTIFICATION=C

attached base packages:
[1] splines   stats     graphics  utils     datasets  grDevices methods
base


Dr Oleg Sklyar
Research Technologist
AHL / Man Investments Ltd
+44 (0)20 7144 3803
oskl...@ahl.com

**********************************************************************
  Please consider the environment before printing this email or its attachments.
The contents of this email are for the named addressees ...{{dropped:19}}

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to