2011-10-26 6 views
16

कल मैं विधेयक Venables से सीखा कि कैसे स्थानीय() स्थिर कार्यों और चर, जैसे बनाने में मदद कर सकते हैं,स्थानीय() आर में बंद होने के लिए अन्य दृष्टिकोणों से अलग कैसे है?

example <- local({ 
    hidden.x <- "You can't see me!" 
    hidden.fn <- function(){ 
    cat("\"hidden.fn()\"") 
    } 
    function(){ 
    cat("You can see and call example()\n") 
    cat("but you can't see hidden.x\n") 
    cat("and you can't call ") 
    hidden.fn() 
    cat("\n") 
    } 
}) 

जो के रूप में कमांड प्रॉम्प्ट से इस प्रकार व्यवहार करती है:

> ls() 
[1] "example" 
> example() 
You can see and call example() 
but you can't see hidden.x 
and you can't call "hidden.fn()" 
> hidden.x     
Error: object 'hidden.x' not found 
> hidden.fn() 
Error: could not find function "hidden.fn" 

मैं इस देखा है Static Variables in R में चर्चा की गई एक बात जहां एक अलग दृष्टिकोण नियोजित किया गया था।

क्या पेशेवरों और इन दोनों तरीकों की विपक्ष?

उत्तर

12

Encapsulation

प्रोग्रामिंग की इस शैली का लाभ यह है कि छिपा वस्तुओं की संभावना कुछ और द्वारा ओवरराइट नहीं किया जाएगा ताकि आप और अधिक आत्मविश्वास उनमें शामिल आप क्या सोचते हैं हो सकता है। उनका उपयोग गलती से नहीं किया जाएगा क्योंकि उन्हें आसानी से एक्सेस नहीं किया जा सकता है। में लिंक्ड करने के लिए सवाल ही नहीं एक वैश्विक चर, count, जो पहुँचा और कहीं भी यदि ऐसा है तो हम कोड डिबगिंग और count देख रही है और देख रहे हैं से ओवरराइट किया जा सकता है में पोस्ट अपनी बदल हम वास्तव में यकीन है कि कोड का क्या हिस्सा है हो ऐसे ही चल नहीं उसे बदल दिया। इसके विपरीत, प्रश्न के उदाहरण कोड में हमें अधिक आश्वासन है कि कोड का कोई अन्य भाग शामिल नहीं है।

ध्यान दें कि हम वास्तव में हालांकि इसके कि आसान नहीं छिपा समारोह का उपयोग कर सकते हैं:

# run hidden.fn 
environment(example)$hidden.fn() 

ऑब्जेक्ट ओरिएंटेड प्रोग्रामिंग

भी ध्यान रखें कि इस ओरिएंटेड प्रोग्रामिंग जहां example और hidden.fn आपत्ति करने के लिए बहुत करीब है विधियां हैं और hidden.x एक संपत्ति है। हम इसे इस तरह से कर सकता यह स्पष्ट करने के लिए:

library(proto) 
p <- proto(x = "x", 
    fn = function(.) cat(' "fn()"\n '), 
    example = function(.) .$fn() 
) 
p$example() # prints "fn()" 

आद्य नहीं छुपाती x और fn लेकिन इसकी उस गलती उन तक पहुंच के बाद से आप जो वास्तव में है कि नहीं है उन तक पहुँच की p$x और p$fn() का उपयोग करना चाहिए आसान नहीं

वस्तु उन्मुख दृष्टिकोण विरासत की संभावना जोड़ता है, जैसे: e <- environment(example); e$hidden.fn()

संपादित लिखने के लिए सक्षम किया जा रहा से अलग एक p का एक बच्चा जो सिवाय यह ओवरराइड करता है कि fnp तरह कार्य करता है निर्धारित कर सकते हैं।

ch <- p$proto(fn = function(.) cat("Hello from ch\n")) # child 
ch$example() # prints: Hello from ch 
6

local() एक सिंगलटन पैटर्न लागू कर सकते हैं - जैसे, snow पैकेज इस का उपयोग करता है एक RMPI उदाहरण है कि उपयोगकर्ता बना सकते हैं ट्रैक करने के लिए।

getMPIcluster <- NULL 
setMPIcluster <- NULL 
local({ 
    cl <- NULL 
    getMPIcluster <<- function() cl 
    setMPIcluster <<- function(new) cl <<- new 
}) 

local() भी एक स्क्रिप्ट में स्मृति का प्रबंधन करने, उदाहरण के लिए, बड़े मध्यवर्ती खंड की अंतिम पंक्ति पर अंतिम वस्तु बनाने के लिए आवश्यक वस्तुओं के आवंटन में इस्तेमाल किया जा सकता है। बड़े मध्यवर्ती वस्तुओं कचरा संग्रहण जब local रिटर्न के लिए उपलब्ध हैं।

बंद करने के लिए फ़ंक्शन का उपयोग करना एक कारखाना पैटर्न है - bank account उदाहरण के लिए आर प्रलेखन में उदाहरण, जहां हर बार open.account लागू किया जाता है, एक नया खाता बनाया जाता है।

@otsaw उल्लेख के रूप में, Memoization एक क्रॉलर में, स्थानीय, जैसे का उपयोग कर लागू किया जा सकता कैश वेब साइटों के

library(XML) 
crawler <- local({ 
    seen <- new.env(parent=emptyenv()) 
    .do_crawl <- function(url, base, pattern) { 
     if (!exists(url, seen)) { 
      message(url) 
      xml <- htmlTreeParse(url, useInternal=TRUE) 
      hrefs <- unlist(getNodeSet(xml, "//a/@href")) 
      urls <- 
       sprintf("%s%s", base, grep(pattern, hrefs, value=TRUE)) 
      seen[[url]] <- length(urls) 
      for (url in urls) 
       .do_crawl(url, base, pattern) 
     } 
    } 
    .do_report <- function(url) { 
     urls <- as.list(seen) 
     data.frame(Url=names(urls), Links=unlist(unname(urls)), 
        stringsAsFactors=FALSE) 
    } 
    list(crawl=function(base, pattern="^/.*html$") { 
     .do_crawl(base, base, pattern) 
    }, report=.do_report) 
}) 

crawler$crawl(favorite_url) 
dim(crawler$report()) 

(Memoization के सामान्य उदाहरण, फाइबोनैचि संख्या, संतोषजनक नहीं है - की सीमा संख्याएं जो आर के न्यूमेरिक प्रतिनिधित्व को ओवरफ्लो नहीं करती हैं, वह संभवतः कुशलता से पूर्व-गणना वाले मानों की एक लुक-अप तालिका का उपयोग करेगी)। दिलचस्प है कि यहाँ क्रॉलर एक सिंगलटन है; आसानी से कारखाने के पैटर्न का पालन किया जा सकता है, तो प्रति बेस यूआरएल एक क्रॉलर।

+1

'स्थानीय' सुविधाजनक बनाने वाला एक और पैटर्न ज्ञापन है। आर इन्फर्नो में कहीं एक उदाहरण है। – otsaw

+0

क्रॉलर एक सिंगलटन होने के बारे में आपका विचार दिलचस्प है क्योंकि स्थानीय के लिए एक विकल्प बिना किसी तर्क के अज्ञात फ़ंक्शन का मूल्यांकन करना है - एक कारखाना पैटर्न बेस यूआरएल पर बंद होने का उपयोग कर सकता है। – hadley

संबंधित मुद्दे

 संबंधित मुद्दे