Runtime question: how to un-observe (or sliently delete) a variable?

Hello and please consider the following contrived example, made to demonstrate what happens when an observed variable is deleted some time after its creation:

// create the variable
const variable = new Runtime()
  .variable({ fulfilled: console.log })
  .define('myVariable', 'Return value of the soon-to-be-deleted variable')

// later, delete the variable
setTimeout(() => {
}, 100)

Here’s the output of this code:

> "Return value of the soon-to-be-deleted variable" "myVariable"
> undefined null

First line, as expected, logs the value of the variable as well as its name, which (TIL) is passed as the 2nd arg to fulfilled().

The 2nd output line is also logged by fulfilled(), as a result of calling variable.delete(). I.e. deleting the variable redefines its value to be undefined and its name to be null. This was a surprise; I was expecting deletion to be silent. I now realize that the triggering of an event upon deletion is necessary, because any variables that depend on the deleted variable need to be re-evaluated.

But, in my case, I need to ignore any calls to fulfilled()if they’re triggered by deletion. Do you have any suggestions for how to properly achieve this? The 2 non-ideal options that come to mind are:

  1. Set a flag prior to calling variable.delete() and check that flag inside fulfilled()
  2. Rely on the fact that deletion nullifies the variable name to ascertain that it’s been deleted.

Neither option is great. I think a cleaner way would be to somehow un-observe the variable just before deletion, but I haven’t found a documented way of doing so.

Appreciate any tips!

You could do something like this:

// later, delete the variable
setTimeout(() => {
  variable._observer = {};
}, 100)

Though I’m not sure if it’s a good idea to rely on changing “private” properties like this.

Would you mind elaborating a little bit more about what kind of computation you’re trying to perform with this pattern? I think that would help us understand the intended use case.

After all, if you want the rest of your computation graph to remain current with the final observed value of myVariable … then why delete it at all? Why not just leave it as it is?

Edit: I wasn’t understanding — and needed to read your post a second time.

Thanks for the replies. @bgchen 's suggestions is what I’ve been looking for, except I too am concerned about the reliance on private properties.

@jashkenas I realize that the info I provided raises the question of why or whether silent deletion is necessary. Unfortunately it’d be difficult to fully explain the use case in this forum, but I’ll attempt to, in a nutshell… I (gratefully) use the Runtime with custom UI to let users assemble a DAG-like data-processing pipeline. Each node in that pipeline is implemented as a Runtime module with named variables serving as that node’s input(s) and output(s). Conveniently, those nodes’ inputs/outputs are then strung together using variable.import() from one module (i.e. node) to another. Observers are used to report on the output(s) of each node in the pipeline.

In this use case, users can delete pipeline nodes, which in Runtime terms deletes an entire module. AFAIK deleting a module is done by looping over and deleting all its variables. This deletion ends up calling to those variables’ observers, which appears to the observer as if data is “moving through” the pipeline whereas in reality those are just variables being disposed of – whose changes need to be ignored. Hope that sheds a bit of light.

1 Like