如何持久存储对象的值而不是其名称? [英] How to persistently store value of an object instead of its name?

查看:99
本文介绍了如何持久存储对象的值而不是其名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我相关问题的延续:值"(重要数据"),但是如您所见,我检索了对象本身的名称("sf.data.devLinks").我怀疑可能是因为我使用as.name造成的,但是我在交互式会话中另外测试了一个原始示例,并且as.name正常工作.如您所见,我也尝试使用evalsubstitute,但没有帮助.

This is in continuation of my related question: Error when trying to interactively load data file saved by paused batch script. I decided to present my question with a reproducible example separately to avoid making the already large description in the previous question even bigger. In the following reproducible example, I expect to retrieve the value of the stored object ("Important data"), but instead, as you see, I retrieve the name of the object itself ("sf.data.devLinks"). I suspected that it could be because of me using as.name, but I tested additionally a primitive example in an interactive session and as.name worked fine. I also, as you see, have tried using eval and substitute, but it didn't help.

library(RCurl)

info <- "Important data"
ATTR <- "SQL"
request <- "SELECT info FROM topSecret"
dataName <- "sf.data.devLinks"
rdataFile <- "/tmp/testAttr.rds"

save <- TRUE

getData <- function() {
  return (info)
}

requestDigest <- base64(request)

# check if the archive file has already been processed
message("\nProcessing request \"", request, "\" ...\n")

# read back the object with the attribute
if (file.exists(rdataFile)) {
  # now check if request's SQL query hasn't been modified
  data <- readRDS(rdataFile)
  message("Retrieved object '", data, "', containing:\n")
  message(str(data))

  requestAttrib <- attr(data, ATTR, exact = TRUE)
  if (is.null(requestAttrib)) {
    message("Object '", data, "' doesn't have attribute \"",
            ATTR, "\"\n")
  }
  else {
    message("Object '", data, "' contains attribute ", ATTR, ":\n\"",
            base64(requestAttrib), "\"\n")

    if (identical(requestDigest, requestAttrib)) {
      message("Processing skipped: RDS file is up-to-date.\n")
      save <- FALSE
      return
    }
  }
  rm(data)
}

if (save) {
  message("Saving results of request \"",
          request, "\" as R data object ...\n")

  assign(dataName, getData())
  data <- as.name(dataName)
  #eval(substitute(assign(dataName, getData()),
  #                list(data <- as.name(dataName))))

  # save hash of the request's SQL query as data object's attribute,
  # so that we can detect when configuration contains modified query
  attr(data, ATTR) <- base64(request)

  # save current data frame to RDS file
  saveRDS(data, rdataFile)
}

请注意,测试此代码需要运行两次(第一次运行-存储对象,第二次-检索).

Please note that testing this code requires running it twice (first run - to store the object, second - to retrieve).

推荐答案

最后,我能够回到这个问题.我已经找到了正确的解决方案,所以我在回答自己的问题.答案基于我的可重现示例,但是我已经对更复杂的真实世界R代码进行了相应的更改. 解决方案非常简单,但是双重,如下所示.

Finally, I was able to return to this question. I have figured out the correct solution, so I'm answering my own question. The answer here is based on my reproducible example, but I have made corresponding changes in my more complex real-world R code. The solution is rather simple, but twofold, as follows.

  1. assign(dataName, readRDS(rdataFile))替换原始代码data <- readRDS(rdataFile).

get(dataName)替换原始代码as.name(dataName). eval(parse(text=dataName))的替代方法是eval(parse(text=dataName)),恕我直言,这很麻烦.

Replace the original code as.name(dataName) with get(dataName). An alternative to get() here is eval(parse(text=dataName)), which IMHO is more cumbersome.

下面,我根据原始的可复制示例提供了解决方案的完整源代码.我不提供易于重现的脚本输出(请记住至少要运行两次脚本).再次感谢所有为这个问题提供帮助的人.

Below I provide the solution's full source code, based on the original reproducible example. I don't provide the script's output, which is easy to reproduce (remember to run script at least twice). Again, thanks to everyone who helped with this question.

library(RCurl)

info <- "Important data"
ATTR <- "SQL"
request <- "SELECT info FROM topSecret"
dataName <- "sf.data.devLinks"
rdataFile <- "/tmp/testAttr.rds"

save <- TRUE

getData <- function() {
  return (info)
}

requestDigest <- base64(request)

# check if the archive file has already been processed
message("\nProcessing request \"", request, "\" ...\n")

# read back the object with the attribute
if (file.exists(rdataFile)) {
  # now check if request's SQL query hasn't been modified
  assign(dataName, readRDS(rdataFile))
  message("Retrieved object '", dataName, "', containing:\n")
  message(str(get(dataName)))

  requestAttrib <- attr(get(dataName), ATTR, exact = TRUE)
  if (is.null(requestAttrib)) {
    message("Object '", dataName, "' doesn't have attribute \"",
            ATTR, "\"\n")
  }
  else {
    message("Object '", dataName, "' contains attribute \"",
            ATTR, "\":\n\"", base64(requestAttrib), "\"\n")

    if (identical(requestDigest, requestAttrib)) {
      message("Processing skipped: RDS file is up-to-date.\n")
      save <- FALSE
      return
    }
  }
}

if (save) {
  message("Saving results of request \"",
          request, "\" as R data object ...\n")

  assign(dataName, getData())
  message(str(dataName))
  data <- get(dataName)
  # alternative to using get(), but more cumbersome:
  # data <- eval(parse(text=dataName))

  # save hash of the request's SQL query as data object's attribute,
  # so that we can detect when configuration contains modified query
  attr(data, ATTR) <- base64(request)

  message(str(data))

  # save current data frame to RDS file
  saveRDS(data, rdataFile)
}

这篇关于如何持久存储对象的值而不是其名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆