R 重写非默认方法并避免递归

R 重写非默认方法并避免递归,r,recursion,dispatch,generic-function,R,Recursion,Dispatch,Generic Function,当使用泛型函数系统分派调用原始方法的修改方法时,哪些编程原则可以帮助我避免递归 背景 出于前面讨论的原因,我对bit64::as.integer64.character()的行为不满意,因此我编写了一个变通函数,它调用bit64::as.integer64(),然后对输出进行一些更改: test_string <- c('1234','5678','', 'Help me Stack Overflow') # illustration of undesired behavior: lib

当使用泛型函数系统分派调用原始方法的修改方法时,哪些编程原则可以帮助我避免递归

背景 出于前面讨论的原因,我对
bit64::as.integer64.character()
的行为不满意,因此我编写了一个变通函数,它调用
bit64::as.integer64()
,然后对输出进行一些更改:

test_string <- c('1234','5678','', 'Help me Stack Overflow')

# illustration of undesired behavior:
library(bit64)
as.integer64(test_string) # returns int64 [1] 1234 5678 0 <NA> without warning

# workaround:    
charToInt64 <- function(s){
  stopifnot( is.character(s) )
  x <- bit64::as.integer64(s)
  # as.integer64("") unexpectedly returns zero without warning.  
  # Overwrite this result to return NA without warning, similar to base as.integer("")
  x[s==""] <- NA_integer64_
  # as.integer64("ABC") unexpectedly returns zero without warning.
  # Overwrite this result to return NA with same coercion warning as base as.integer("ABC")
  bad_strings <- grepl('\\D',s)
  if( any(bad_strings) ){
    warning('NAs introduced by coercion')
    x[bad_strings] <- NA_integer64_  
  }
  x
}

# Demo of workaround -- this behavior mimics base as.integer():
charToInt64(test_string) # returns int64 [1] 1234 5678 <NA> <NA> with warning
charToInt64(head(test_string,-1)) # returns int64 [1] 1234 5678 <NA> without warning
第二次尝试(有效,但我不明白为什么) 将对通用函数
bit64::as.integer64
的调用替换为对字符串方法
bit64::as.integer64.character
的调用可以解决此问题

charToInt64v2 <- function(s){
  stopifnot( is.character(s) )
  x <- bit64::as.integer64.character(s) # this is the only change
  x[s==""] <- NA_integer64_
  bad_strings <- grepl('\\D',s)
  if( any(bad_strings) ){
    warning('NAs introduced by coercion')
    x[bad_strings] <- NA_integer64_  
  }
  x
}
as.integer64.character <- charToInt64v2 
as.integer64(test_string) # works as desired

ChartPoint64v2问得好,玩了几分钟就到不了任何地方。也许这与调用重定义字符方法的初始
bit64::as.integer64(s)
有关,该方法每次都必须再次调用
bit64::as.integer64(s)
?但看起来不应该发生这种情况。您的第一次尝试使用一个通过泛型函数间接调用方法本身的函数来屏蔽该方法。因此,无限递归。第二次尝试使用专门调用原始方法的函数屏蔽该方法。因此,没有递归。这是个好问题,只需几分钟的时间,就不会有结果。也许这与调用重定义字符方法的初始
bit64::as.integer64(s)
有关,该方法每次都必须再次调用
bit64::as.integer64(s)
?但看起来不应该发生这种情况。您的第一次尝试使用一个通过泛型函数间接调用方法本身的函数来屏蔽该方法。因此,无限递归。第二次尝试使用专门调用原始方法的函数屏蔽该方法。因此,没有递归。
charToInt64v2 <- function(s){
  stopifnot( is.character(s) )
  x <- bit64::as.integer64.character(s) # this is the only change
  x[s==""] <- NA_integer64_
  bad_strings <- grepl('\\D',s)
  if( any(bad_strings) ){
    warning('NAs introduced by coercion')
    x[bad_strings] <- NA_integer64_  
  }
  x
}
as.integer64.character <- charToInt64v2 
as.integer64(test_string) # works as desired