From jmc at r-project.org  Thu Jul 22 01:45:14 2010
From: jmc at r-project.org (John Chambers)
Date: Wed, 21 Jul 2010 16:45:14 -0700
Subject: [Rd] Bug: broken exception handling in S4 methods
In-Reply-To: <1A68FCB28DE72F4BA3B967E6506CCE430662B360@mildnpexmb01.maninvestments.ad.man.com>
References: <1A68FCB28DE72F4BA3B967E6506CCE430662B360@mildnpexmb01.maninvestments.ad.man.com>
Message-ID: <4C47868A.5010702@r-project.org>

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
> osklyar at 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 at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
>



[Rd] Bug: broken exception handling in S4 methods
John Chambers