Любой способ получить доступ к функции, установленной makeActiveBinding?

Название в основном говорит само за себя.

Если я сделаю это...

makeActiveBinding("x", function() runif(2), .GlobalEnv)
x
# [1] 0.7332872 0.4707796
x
# [1] 0.5500310 0.5013099

... есть ли у меня какой-либо способ изучить x, чтобы узнать, с какой функцией он связан (и если нет, то почему)?

(В этом случае я хотел бы узнать, что x было определено как function() runif(2).)


person Josh O'Brien    schedule 17.04.2013    source источник
comment
Ромен Франсуа предложил R-devel патч в 2009 году изменить это поведение (см. ссылку на вложение с код C)   -  person Andrie    schedule 18.04.2013
comment
@Andrie, этот патч не дал функции привязки, просто напечатайте, что это действительно активная привязка   -  person Romain Francois    schedule 18.04.2013
comment
@Andrie Интересно, но IIUC, похоже, все, что патч Ромена сделает для str(x), будет печатать (или, скорее, cat()) строку ‹активное связывание›\n. Это то, что вы тоже видите?   -  person Josh O'Brien    schedule 18.04.2013
comment
@RomainFrancois - Вы понимаете, что, за исключением взлома C-уровня, детали активной привязки (включая функцию R, на которую она ссылается) скрыты? Является ли то, о чем я прошу, похожим в своей невозможности на желание увидеть внутренности объекта обещания? (В смысле это скрыто, специально?)   -  person Josh O'Brien    schedule 18.04.2013
comment
Он действительно выглядит очень скрытым.   -  person Romain Francois    schedule 18.04.2013
comment
@RomainFrancois - Спасибо. Исходя из вас, я буду считать это по существу авторитетным ответом, если не будет опубликовано что-то еще. Ценю ваш ответ на него!   -  person Josh O'Brien    schedule 18.04.2013


Ответы (1)


Немного повозившись с envir.c, я могу заставить это работать:

#include <Rcpp.h>
using namespace Rcpp ;

#define HASHSIZE(x)      LENGTH(x)
#define HASHVALUE(x)    TRUELENGTH(x)

// [[Rcpp::export]]
SEXP get_binding_fun( std::string name, Environment env){
    SEXP symbol = Rf_install( name.c_str() );
    SEXP tab = HASHTAB(env) ;
    SEXP c = PRINTNAME(symbol);

    // finding the hash code for the symbol
    int hashcode = HASHVALUE(c) % HASHSIZE(tab);

    // get the value there from the hash table
    SEXP res = CAR( VECTOR_ELT(tab, hashcode ) ) ;

    return res ;
}

Сохраните это в файл .cpp, sourceCpp и используйте его с этим кодом R:

> makeActiveBinding("x", function() runif(2), .GlobalEnv)
> get_binding_fun("x", .GlobalEnv)
# function ()
# runif(2)
person Romain Francois    schedule 17.04.2013
comment
Нам не обязательно нужно Rcpp здесь. Мне просто нравится использовать sourceCpp - person Romain Francois; 18.04.2013