निम्नलिखित कोड reproducibly जब आर में मार डाला segfaults (3.0.2 लेकिन मैं इसे अन्य संस्करणों के लिए समान है यह सोचते हैं रहा हूँ):सेटिंग parent.env, `detach` द्वारा पीछा किया, segfaults
ns = new.env(parent = .BaseNamespaceEnv)
local(f <- function() 42, envir = ns)
x = list2env(as.list(ns), parent = as.environment(2))
parent.env(.GlobalEnv) = x
detach()
हाँ, मैं जानते हैं कि documentation on parent.env
कहते
प्रतिस्थापन समारोह
parent.env<-
बेहद खतरनाक के रूप में यह तरीके कि आंतरिक सी कोड द्वारा बनाई गई मान्यताओं का उल्लंघन में विध्वंस परिवर्तन वातावरण के लिए इस्तेमाल किया जा सकता है। इसे निकट भविष्य में हटाया जा सकता है।
यही वह है जो मुझे यहां चल रहा है। हालांकि, मैं क्यों समझना चाहूंगा यह व्यवहार इस तरह से है, और इससे कैसे बचें।
निम्नलिखित सरल कोड करता इस समस्या नहीं है:
x = new.env(parent = as.environment(2))
local(f <- function() 42, envir = x)
parent.env(.GlobalEnv) = x
detach()
... इसलिए ऐसा लगता है कि यह एक अंतर यह है कि x
एक समारोह जिसका parent.env
एक अलग (स्वाधीन) वातावरण होता है बनाता है।
इसी तरह, parent.env<-
के बजाय attach
का उपयोग करके कोई क्रैश नहीं होता है। (तो क्यों बस attach
का उपयोग नहीं? क्योंकि मेरे कोड में, .GlobalEnv
हिस्सा एक चर जो विभिन्न वातावरण का उल्लेख कर सकते है।)
क्रैश डम्प मुझसे कहता है कि segfault do_detach
(envir.c
) में होता है। शायद यह संबंधित है -
isSpecial = IS_USER_DATABASE(s);
if(isSpecial) {
R_ObjectTable *tb = (R_ObjectTable*) R_ExternalPtrAddr(HASHTAB(s));
if(tb->onDetach) tb->onDetach(tb);
}
मैं है पता नहीं क्या IS_USER_DATABASE
करता है: कोड निम्नलिखित लाइनों में शामिल है? केवल मेरे पर्यावरण (.onDetach = function (x) x
) में .onDetach
विधि जोड़ने से मदद नहीं मिली।
मुझे लगता है कि आपको आर-डेवेल पर पूछना होगा। Globalenv के माता-पिता के साथ चारों ओर गड़बड़ करना एक _really_ बुरा विचार की तरह लगता है। – hadley