関数を使用して、対象の変数への変更のログ記録を自動化することもできmakeActiveBinding
ます。次に、ログを使用して、出力をls()
変更時間で並べ替えることができます。
1 つの注意点は、この方法を使用する場合、変数を最初に使用する前に追跡を設定する必要があることです。
.change.log <- list()
track <- function(variable) {
makeActiveBinding(variable,
function(v)
if (! missing(v))
.change.log[[variable]] <<- c(.change.log[[variable]],
as.list(Sys.time())),
.GlobalEnv)
}
track('x')
x <- 1
.change.log
x <- 2
.change.log
が変更されるたびx
に、 に指定された無名関数が新しい値と等しい値でmakeActiveBinding
呼び出されます。v
この関数x
は が参照されたときにも呼び出されますが、この場合は何も指定されていないため、値が変更されたときにのみログを更新したい ---v
という条件付きです。missing(v)
編集
さらに検討した結果、より良い代替手段makeActiveBinding
は、関数を介して変更ロガーをインストールすることaddTaskCallback
です。<-
以下のコードは、演算子が最上位で使用されるたびに変数名でタイムスタンプを記録する自動ロガーを作成します。
# define a log maker function. This returns a new logger function
# bound with a fresh log.
mk.log <- function() {
log <- list()
# handler functions have to have these four args, but we only use the first.
function(expr, value, ok, visible) {
if (class(expr) == '<-') {
# convert the assignment call to a list, so the
# variable name can be extracted
call.list <- as.list(expr)
# extract the name of the variable being affected, and
# convert it to character, so we can use it as a list name
variable <- as.character(call.list[[2]])
# append a timestamp to the log for this variable
log[[variable]] <<- c(log[[variable]], list(Sys.time()))
}
# callback handlers need to return a bool
return(TRUE)
}
}
# assign the handler to .log, and install it.
addTaskCallback(.log <- mk.log(), name='log')
x <- 5
x <- 10
y <- 4
# read the log
environment(.log)$log
# $x
# $x[[1]]
# [1] "2013-01-25 10:24:26.581 EST"
#
# $x[[2]]
# [1] "2013-01-25 10:24:26.585 EST"
#
#
# $y
# $y[[1]]
# [1] "2013-01-25 10:24:26.589 EST"