【问题标题】:Dispatch `:=` on second argument在第二个参数上调度`:=`
【发布时间】:2020-05-13 23:38:46
【问题描述】:

我想实现一个函数:=(lhs, rhs),它接受lhs任何 表达式,而rhs 必须属于X 类。

为了避免与其他包(例如data.table)发生冲突,应通过setGeneric(":=") 设置一个通用函数:=,该函数基于第二个参数的类进行调度。

然而,

setMethod(
  ":="
  , c("ANY", "X")
  , function(lhs, rhs) NULL
)

假设第一个参数是一个实际的对象,即bla := x 结果

:=(bla, x) 中的错误:找不到对象“bla”

只要bla 未绑定。

当第二个参数属于X 类时,有没有办法定义这样一个函数而不影响其他同名实现的行为?

备注: := 不能定义为适当的 S3 泛型,因为它是在 lhs 而不是 rhs 上调度的。

【问题讨论】:

    标签: r operator-overloading s4


    【解决方案1】:

    你需要说signature("ANY","X")而不是向量

    setGeneric(":=", function(lhs,rhs) standardGeneric(":="))
    setMethod(":=", signature("ANY","ANY"), function(lhs,rhs){print("Default")})
    setMethod(":=", signature("ANY","foo"), function(lhs,rhs){print("foo Method")})
    
    bla <- 1:10
    bar <- 1:10
    class(bar) <- "foo"
    
    bla:=bla
    #Default
    bla:=bar
    #foo Method
    

    【讨论】:

    • 猜你的意思是signature而不是structure。这并不能解决问题:如果 bla 未定义,bla := bar 会导致错误。
    • 是的,我的意思是上半部分signature。我提供的代码块应该是可重现的。请参阅S4 指南了解更多信息
    • 如果你试图调用一个函数,其中 lhs 参数没有在任何环境中定义,那么我认为错误是不可避免的。似乎您想要某种惰性评估-e.i.该符号仅在以某种方式评估时才被访问。我不确定 S4 是否存在此功能,因为访问两者的类签名是为了决定调度。
    • 这正是我正在寻找的,我也担心 S4 不允许这样做。目的是在函数体中使用substitute(lhs),为此目的需要取消评估lhs。任何其他想法,如何定义 := 而不从其他包中拧紧实现(反之亦然)?或者是否有一个二元运算符首先评估 rhs?
    • '通用函数签名中的所有参数都将在函数被调用时进行评估,而不是使用惰性评估。因此,从签名中排除任何需要以符号方式处理的参数(例如函数的 expr 参数)是很重要的。请注意,仅计算实际参数,而不是默认表达式。缺少的参数作为“缺少”类进入方法选择。 - source
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2021-11-20
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多