检索由shiny::reactive()推断的反应性依赖关系

Rap*_*ter 5 r reverse-engineering reactive-programming shiny

考虑一下Joe Cheng 的演讲,他解释了他和他的同事如何在闪亮中实现响应式框架(受到Meteor的启发):

在此输入图像描述

实际问题

有人可以向我解释一下我将如何去查找自动推断出的反应式对象的依赖项(即列出它们的名称和环境,实际访问它们等)shiny::reactive()

更具体地说,我想在我的自定义“一站式”功能setShinyReactive(包reactr)中使用该信息,该功能构建在闪亮的功能之上。

它必须以某种方式可以通过这些组件/类之一的方法实现:

  1. 抗导体(我猜主要是类shiny::Observable
  2. 反应性端点/观察者(我猜主要是类shiny::Observer
  3. 反应式上下文(我猜主要是类shiny::Contextshiny::ReactiveEnvironment

但我仍然对这方面的实际细节感到困惑。

尽职调查

您可以在这里找到我用于逆向工程工作的闪亮版本的分叉版本。.Rnw文件代表了我目前的知识状况以及有关实际实施的问题。

简短的例子shiny::reactive()

require(shiny)
## Ensure that shiny let's us do our thing //
shiny_opt <- getOption("shiny.suppressMissingContextError")
if (is.null(shiny_opt) || !shiny_opt) {
  options(shiny.suppressMissingContextError = TRUE)  
}

a <- 10
shiny::makeReactiveBinding("a")
b <- shiny::reactive(a * 2)
## --> this leads to the inferred result that `b` depends on `a`; 
## this information is stored somewhere in the shiny framework 
## --> that's what I want to get at
b()

a <- 20
b()
Run Code Online (Sandbox Code Playgroud)

背景:双向绑定

我希望能够做到这一点的原因是我希望能够通过原始(或仅稍作修改)的闪亮功能指定双向反应式绑定(例如,请参阅此README)。

到目前为止,乔一直非常乐于助人,也很专注,但他的时间也很短,他让我开始了以下内容:

require(shiny)
## Ensure that shiny let's us do our thing //
shiny_opt <- getOption("shiny.suppressMissingContextError")
if (is.null(shiny_opt) || !shiny_opt) {
  options(shiny.suppressMissingContextError = TRUE)  
}

suppressWarnings(rm(a, b))
options(shiny.suppressMissingContextError=TRUE)
makeReactiveBinding("a")
makeReactiveBinding("b")
observe(a <<- b)
observe(b <<- a)
shiny:::setAutoflush(TRUE)
(a <- 1)
b
(b <- 2)
a
(a <- 3)
b
Run Code Online (Sandbox Code Playgroud)

然而,为了将其集成到我的实现中setShinyReactive,我需要弄清楚该语句o$.value <<- v当前第 203 行)是否有效:

## Call to 'makeActiveBinding' //
makeActiveBinding(
  id,
  env = where,
  fun = local({
    visible
    o
    function(v) {
      if (missing(v)) {

      } else {
        if (strict_set == 0) {
          o$.value <<- v    
          ## --> this should only be allowed for bi-directional relationships
        } else if (strict_set == 1) {

          [...]

        } else if (strict_set == 2) {

          [...]

        }
      }
      [...]
    }
  })
)
Run Code Online (Sandbox Code Playgroud)

这仅适用于双向电抗对象,因为它们是一种“混合体”:同时是电抗导体 电抗源。

这就是为什么我需要弄清楚是否存在双向情况- 这反过来又意味着我需要找出每个对象的依赖关系

对于我的另一种“行人”,基于 进行反应性setReactive,我通过方法查询双向依赖关系.hasBidirectional。这就是我想从正确的闪亮实例/类中检索的信息,该实例/类实际上在某处保存了该信息。