R определяет (библиотечный) обратный вызов для завершения сеанса? - PullRequest
2 голосов
/ 06 июля 2010

когда я загружаю библиотеку (с NAMESPACE), функции .onLoad и .onAttach вызываются, как и .onUnload, когда я отсоединяю библиотеку, выгружая пространство имен.

Мне было интересно, определит ли R способ, который избавил бы меня от необходимости отсоединять / выгружать библиотеку вручную в каждом из моих сценариев, использующих библиотеку xxx.

для этого мне понадобится библиотечный хук , который проверяется и вызывается, когда скрипт , использующий библиотеку, заканчивается, если есть такая вещь. Я не нашел его, и я всегда думаю, что есть причина, почему вещи есть, а также почему их нет.

Я понимаю, из файлов справки и из комментариев, что есть .Last хук скрипта , который я могу использовать, но я ищу что-то похожее на конструктор / деструктор: как только библиотека «выходит из области видимости» (поскольку скрипт, использующий ее, заканчивается), будет вызван «деструктор библиотеки».


другими словами, мне интересно, возможно ли вообще, чтобы скрипт содержал только две строки

#!/usr/bin/Rscript
library(xxx)

и библиотека xxx с NAMESPACE и файл zzz.R, содержащий среди прочего этот

.onLoad <- function(libpath, pkgname) {
  packageStartupMessage("loading ", libpath, '::', pkgname)
}

.onUnload <- function(pkgpath) {
  packageStartupMessage("unloading ", pkgpath)
}

производит этот вывод

loading /usr/local/lib/R/site-library::xxx
unloading /usr/local/lib/R/site-library/xxx

или если мне нужно явно вызвать detach('package:NenS', unload=TRUE) в каждом сценарии, используя библиотеку xxx.

1 Ответ

1 голос
/ 08 февраля 2012

Это немного устарело, но стоит ответить, так как оно относится к покрытию кода, а инструменты R для покрытия кода примитивны.

Если вы хотите совместить что-то вместе, вы можете использовать foodweb() в пакете mvbutils, чтобы определить, какие функции или вызовы в вашем скрипте зависят от других функций из данного пакета.

Затем программа может искать последнюю зависимость в вызывающем коде и сразу после нее вставлять detach(...) в тело.

Единственная проблема заключается в том, что код не должен выполняться в буквально последовательном порядке, а зависимости могут быть достаточно глубокими или непрозрачными, если выполнение функции не является явным (например, eval(parse(text = myCmd)) - каково значение myCmd? Это могло быть установлено через myCmd <- "library(myPackage)"). Точно так же, если инструкция вызывает функцию, которая впоследствии выполняет library(myPackage), ваш пакет будет загружен снова. Однако foodweb может обнаруживать такие явные утверждения, как я и искал такие зависимости.

Если вы хотите выполнить анализ данных времени выполнения, вы можете использовать вывод Rprof, который будет намного лучше понять, использовалась ли зависимость, но в настоящее время выполняется сопоставление строк кода со стеком вызовов. испытывающий. Тем не менее, вы могли бы использовать Rprof плюс специализированный обратный вызов для записи прогресса в скрипте и попытаться сопоставить строки кода со стеком вызовов, а затем с зависимостями. Проблема здесь в том, что это всего лишь одно исполнение.

Итак, короткий ответ заключается в том, что с помощью динамического (во время выполнения) анализа можно увидеть, использовалась ли зависимость для данной серии в данной строке, но не гарантируется, что это можно сделать из статического анализа. .

...