[R-pkg-devel] tryCatch defensive programming guidance

Berry Boessenkool berryboessenkool at hotmail.com
Wed Mar 1 15:52:10 CET 2017


Hi Glenn,


Better late than never:

couldn't you simply use try?


result <- try(  log("a")  )


The printing is horrible: people will think an error occured (but the function didn't stop!)

I tend to use it like this (which may be totally unintended):



res <- try(log("a"), silent=TRUE)
if(inherits(res, "try-error"))
{
 message("log failed: ",res,". Now continuing with res=0.")
 res <- 0
}




See here for my version that captures errors/warnings/messages with call tracing:

https://www.rdocumentation.org/packages/berryFunctions/topics/tryStack


Regards,

Berry


________________________________
From: R-package-devel <r-package-devel-bounces at r-project.org> on behalf of Glenn Schultz <glennmschultz at me.com>
Sent: Saturday, February 25, 2017 15:50
To: R Package Development
Subject: [R-pkg-devel] tryCatch defensive programming guidance

All,

I have the following to create a class PriceTypes.  I use try catch on the function and it gives me the error

price <- tryCatch(PriceTypes(price = "100")
,error = function(e) print(e)
,warning = function(w) print(w))

<simpleError in PriceTypes(price = "100"): tail value is missing>
>

I read the section on tryCatch and withCallingHandlers as well the manual but I am still not clear as to how to use tryCatch in the function below I tried
PriceTypes <- TryCatch(
                                          function(){}
                                          ), function(e) print(error)

but this is obviously wrong as it did not work.  My question can I use tryCatch in the function itself or only when I invoke the function.

Best Regards,
Glenn

#' An S4 class representating bond price
#'
#' This class is used to create and pass the price types reported to
#' investors and used in analytics. For example price is often reported as
#' decimal or fractions 32nds to investors but price basis (price/100) is
#' used to calculate proceeds and compute metrics like yield, duration, and
#' partial durations.
#' @slot PriceDecimal A numeric value the price using decimal notation
#' @slot Price32nds A character the price using 32nds notation
#' @slot PriceBasis A numeric value price decimal notation in units of 100
#' @slot PriceDecimalString A character the price using decimal notation
#' @exportClass PriceTypes
setClass("PriceTypes",
representation(
PriceDecimal = "numeric",
Price32nds = "character",
PriceBasis = "numeric",
PriceDecimalString = "character")
)

setGeneric("PriceTypes", function(price = numeric())
{standardGeneric("PriceTypes")})

#' A standard generic function get the slot PriceDecimal
#'
#' @param object an S4 object
#' @export PriceDecimal
setGeneric("PriceDecimal", function(object)
{standardGeneric("PriceDecimal")})

#' A standard generic function to set the slot PriceDecimal
#'
#' @param object an S4 object
#' @param value the replacement value of the slot
#' @export PriceDecimal<-
setGeneric("PriceDecimal<-", function(object, value)
{standardGeneric("PriceDecimal<-")})

#' A standard generic function to get the slot Price32nds
#'
#' @param object an S4 object
#' @export Price32nds
setGeneric("Price32nds", function(object)
{standardGeneric("Price32nds")})

#' A standard generic function to set the slot Price32nds
#'
#' @param object an S4 object
#' @param value the replacement value of the slot
#' @export Price32nds<-
setGeneric("Price32nds<-", function(object, value)
{setGeneric("Price32nds")})

#' A standard generic to get the slot PriceBasis
#'
#' @param object an S4 object
#' @export PriceBasis
setGeneric("PriceBasis", function(object)
{standardGeneric("PriceBasis")})

#' A standard generic to set the slot PriceBasis
#'
#' @param object A S4 object of type PriceTypes
#' @param value the replacement value of the slot
#' @export PriceBasis<-
setGeneric("PriceBasis<-", function(object, value)
{standardGeneric("PriceBasis<-")})

#' A standard generic to get the slot PriceDecimalString
#'
#' @param object A S4 object of the type PriceTypes
#' @export
setGeneric("PriceDecimalString", function(object)
{setGeneric("PriceDecimalString")})

#' A standard generic to set the slot PriceDecimalString
#'
#' @param object A S4 object of the type PriceTypes
#' @param value The replacement value of the slot
#' @export
setGeneric("PriceDecimalString<-", function(object, value)
{setGeneric("PriceDecimalString<-")})

setMethod("initialize",
signature("PriceTypes"),
function(.Object,
PriceDecimal = numeric(),
Price32nds = "character",
PriceBasis = numeric(),
PriceDecimalString = "character",
...){
callNextMethod(.Object,
PriceDecimal = PriceDecimal,
Price32nds = Price32nds,
PriceBasis = PriceBasis,
PriceDecimalString = PriceDecimalString,
...)
})
#' A method to extract PriceDecimal from slot of class PriceTypes
#'
#' @param object an S4 object of the type PriceTypes
#' @exportMethod PriceDecimal
setMethod("PriceDecimal", signature("PriceTypes"),
function(object){object at PriceDecimal})

#' A method to set PriceDecimal in slot of class PriceTypes
#'
#' @param object an S4 object of the typre PriceTypes
#' @param value the replacement value of the slot
#' @exportMethod PriceDecimal<-
setReplaceMethod("PriceDecimal", signature("PriceTypes"),
function(object, value){
object at PriceDecimal <- value
return(object)
})

#' A method to extract Price32nds from slot of class PriceTypes
#'
#' @param object an S4 object of the type PriceTypes
#' @exportMethod Price32nds
setMethod("Price32nds", signature("PriceTypes"),
function(object){object at Price32nds})

#' A method to set Price32nds in slot of class PriceTypes
#'
#' @param object an S4 object of the type PriceTypes
#' @param value the replacement value of the slot
setReplaceMethod("Price32nds", signature("PriceTypes"),
function(object, value){
object at Price32nds <- value
return(object)
})

#' A method to extract PriceBasis from slot of class PriceTypres
#'
#' @param object an S4 object of the type PriceType
#' @exportMethod PriceBasis
setMethod("PriceBasis", signature("PriceTypes"),
function(object){object at PriceBasis})

#' a method to set PriceBasis from slot of class PriceTypes
#'
#' @param object an S4 object of the type PriceTypes
#' @param value the replacement value of the slot
#' @exportMethod PriceBasis<-
setReplaceMethod("PriceBasis", signature("PriceTypes"),
function(object, value){
object at PriceBasis <- value
return(object)
})

#' A method to extract PriceDecimalString from slot of class PriceTypes
#'
#' @param object an S4 object of type PriceTypes
#' @exportMethod PriceDecimalString
setMethod("PriceDecimalString", signature("PriceTypes"),
function(object){object at PriceDecimalString})

#' A method to set PriceDecimalString from slot of class PriceTypes
#'
#' @param object an S4 object of type PriceTypes
#' @param value the replacement value of the slot
#' @exportMethod PriceDecimalString<-
setReplaceMethod("PriceDecimalString", signature("PriceTypes"),
function(object, value){
object at PriceDecimalString <- value
return(object)})

#' PriceTypes is a constructor function for the class PriceTypes
#'
#' @param price character the price in either
#' decimal notation (example "100.125") or 32nds notation (example "100-4")
#' @export PriceTypes
PriceTypes <- function(price){
PriceBasis = 100
Units = 32

if(mode(price) != "character") stop ("price must be a character")
if(is.na(strsplit(price, "\\.|\\-")[[1]][2]) == TRUE) stop (
"tail value is missing")

Convertto32nds <- function(Price = "character"){
#convert price to numeric value
Price = as.numeric(Price)
tail32nds = round(x = (Price - floor(x = Price)) * 32, digits = 4)
Price = paste(as.character(floor(x=Price)),
"-",
as.character(tail32nds),
sep = "")
return(Price)
}

ConverttoDecimal <- function(Price = "character", Units = numeric()){
SplitPrice = strsplit(as.character(Price), "-")
handle = as.numeric(SplitPrice[[1]][1])
TailDecimal = signif(as.numeric(SplitPrice[[1]][2])/Units,8)
TailDecimal = gsub("(^|[^0-9])0+", "\\1", TailDecimal, perl = TRUE)
Price = paste(as.character(handle),
as.character(TailDecimal),sep="")
return(Price)
}

ConverttoString <- function(PriceDecimal = numeric()){
sprintf("%.8f", PriceDecimal)
}

# Convert Price when entered as a decimal value
if(grepl(".", as.character(price), fixed = TRUE) == TRUE){
Price_Decimal = format(as.numeric(price), nsmall =2)
Price_32nds = Convertto32nds(Price = price)
Price_Basis = as.numeric(price) / PriceBasis
Price_Decimal_String = ConverttoString(
PriceDecimal = as.numeric(Price_Decimal))
}

if(grepl("-", as.character(price), fixed = TRUE) == TRUE){
Price_Decimal = ConverttoDecimal(Price = price, Units = Units)
Price_32nds = price
Price_Basis = as.numeric(Price_Decimal)/PriceBasis
Price_Decimal_String = ConverttoString(
PriceDecimal = as.numeric(Price_Decimal))
}

new("PriceTypes",
PriceDecimal = as.numeric(Price_Decimal),
Price32nds = Price_32nds,
PriceBasis = as.numeric(Price_Basis),
PriceDecimalString = Price_Decimal_String
)
}
______________________________________________
R-package-devel at r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-package-devel

	[[alternative HTML version deleted]]



More information about the R-package-devel mailing list