2012-06-30 12 views
14

मैं एक जिद्दी उपयोग हूं जो का उपयोग <- के बजाय हर समय करता है, और स्पष्ट रूप से कई आर प्रोग्रामर इस पर फहराएंगे। मैंने formatR पैकेज लिखा है जो parser पैकेज के आधार पर प्रतिस्थापित कर सकता है। जैसा कि आप में से कुछ जानते हैं, parser कुछ दिनों पहले सीआरएएन पर अनाथ हो गया था। हालांकि यह अभी वापस है, इसने मुझे इस पर निर्भर रहने में संकोच नहीं किया। मैं सोच रहा हूं कि =<- के साथ सुरक्षित रूप से प्रतिस्थापित करने का दूसरा तरीका है, क्योंकि सभी = का औसत असाइनमेंट नहीं है, उदा। fun(a = 1)। नियमित अभिव्यक्ति विश्वसनीय होने की संभावना नहीं है (mask.inline()formatR में फ़ंक्शन देखें), लेकिन यदि आप मेरा सुधार कर सकते हैं तो मैं निश्चित रूप से इसकी सराहना करता हूं। शायद codetools पैकेज मदद कर सकता है?यह बताने का एक विश्वसनीय तरीका है कि आर कोड में असाइनमेंट के लिए है?

कुछ परीक्षण मामलों:

# should replace 
a = matrix(1, 1) 
a = matrix(
    1, 1) 

(a = 1) 
a = 
    1 

function() { 
    a = 1 
} 

# should not replace 
c(
    a = 1 
) 

c(
    a = c(
    1, 2)) 
+6

अच्छा और उपयोगी ओपन-सोर्स कोड मर नहीं जाता है और जहां गायब हो जाता है --- और पार्सर के पास अब एक नया रखरखाव है जैसा कि कोई उम्मीद करेगा। नौकरी करने वाले परीक्षण उपकरण के आधार पर वास्तव में समस्या कहां है? –

+0

मैं निश्चित रूप से एंड्रयू पर भरोसा करता हूं और समुदाय पार्सर मरने नहीं देगा। वास्तव में मैं [चाहता था] (https://github.com/yihui/knitr/issues/211) अनाथ होने से पहले हाइलाइट/पार्सर पर निर्भरता को हटाने के लिए; यह अपेक्षाकृत छोटी सुविधा के लिए निर्भरता के लायक नहीं है (एक लंबी निर्भरता श्रृंखला में रखरखाव और पैकेज लोडिंग समय जैसी समस्याएं हैं)। –

+1

परेशान क्यों? और "=" को "<" के साथ बदलने का सवाल क्यों है जब आपकी वरीयता पूर्व के लिए है? – mdsumner

उत्तर

4

Kohske formatR पैकेज है जो codetools पैकेज का उपयोग समस्या हल करने के लिए एक pull request भेजा है। मूल विचार कोड कोड के माध्यम से चलने के लिए कोड वॉकर सेट करना है; जब यह = को कार्यात्मक कॉल के प्रतीक के रूप में पहचानता है, तो इसे <- द्वारा प्रतिस्थापित किया जाता है। यह आर: x = 1 की "लिस्प प्रकृति" के कारण है वास्तव में `=`(x, 1) है (हम इसे `<-`(x, 1) द्वारा प्रतिस्थापित करते हैं); बेशक, =fun(x = 1) के पार्स पेड़ में अलग-अलग व्यवहार किया जाता है।

formatR पैकेज (> = 0.5.2) तब से parser पैकेज पर निर्भरता से छुटकारा पा लिया है, और replace.assign अब मजबूत होना चाहिए।

+0

इसके लायक होने के लिए, मैंने अभी सुना है कि पार्सर के कुछ हिस्सों को आधार आर –

+0

में शामिल किया जा सकता है यह अच्छी खबर है !! धन्यवाद, @DirkEddelbuettel –

-3

सबसे सुरक्षित (और शायद सबसे तेजी से) जिस तरह से =<- द्वारा सीधे <- बजाय लिख रहा है यह बदलने का प्रयास करने की जगह।

+0

सच है, लेकिन यदि आपके पास ज़िलियन स्क्रिप्ट हैं जिन्हें आपको "सुंदरता" की आवश्यकता है, तो यह कुछ मदद की जा सकती है। –

+3

यह कहने जैसा है कि व्याकरण जांच कार्यक्रम बेकार हैं क्योंकि आप कभी टाइप नहीं करते हैं ... – flodel

+0

@flodel: '<-' के बजाय '=' टाइप करना IMHO टाइपो नहीं है लेकिन कुछ जानबूझकर है। यह क्रियाओं को संयोजित नहीं करना है और व्याकरण जांच कार्यक्रमों पर पूरी तरह भरोसा करना है ताकि आप इसे कर सकें। – Thierry

4

यह उत्तर नियमित अभिव्यक्तियों का उपयोग करता है। कुछ किनारे के मामले हैं जहां यह असफल हो जाएगा लेकिन अधिकांश कोड के लिए यह ठीक होना चाहिए। यदि आपको सही मिलान की आवश्यकता है तो आपको एक पार्सर का उपयोग करने की आवश्यकता होगी, लेकिन अगर आप समस्याओं में भाग लेते हैं तो regexes हमेशा tweaked किया जा सकता है।

के लिए

#quoted function names 
`my cr*azily*named^function!`(x = 1:10) 
#Nested brackets inside functions 
mean(x = (3 + 1:10)) 
#assignments inside if or for blocks 
if((x = 10) > 3) cat("foo") 
#functions running over multiple lines will currently fail 
#maybe fixable with paste(original_code, collapse = "\n") 
mean(
    x = 1:10 
) 

से सावधान रहें कोड ?regmatches पृष्ठ पर एक उदाहरण पर आधारित है। मूल विचार यह है: प्लेसहोल्डर के लिए फ़ंक्शन सामग्री स्वैप करें, प्रतिस्थापन करें, फिर अपनी फ़ंक्शन सामग्री को वापस रखें।

#Sample code. For real case, use 
#readLines("source_file.R") 
original_code <- c("a = 1", "b = mean(x = 1)") 

#Function contents are considered to be a function name, 
#an open bracket, some stuff, then a close bracket. 
#Here function names are considered to be a letter or 
#dot or underscore followed by optional letters, numbers, dots or 
#underscores. This matches a few non-valid names (see ?match.names 
#and warning above). 
function_content <- gregexpr(
    "[[:alpha:]._][[:alnum:._]*\\([^)]*\\)", 
    original_code 
) 

#Take a copy of the code to modify 
copy <- original_code 

#Replace all instances of function contents with the word PLACEHOLDER. 
#If you have that word inside your code already, things will break. 
copy <- mapply(
    function(pattern, replacement, x) 
    { 
    if(length(pattern) > 0) 
    { 
     gsub(pattern, replacement, x, fixed = TRUE) 
    } else x 
    }, 
    pattern = regmatches(copy, function_content), 
    replacement = "PLACEHOLDER", 
    x = copy, 
    USE.NAMES = FALSE 
) 

#Replace = with <- 
copy <- gsub("=", "<-", copy) 

#Now substitute back your function contents 
(fixed_code <- mapply(
    function(pattern, replacement, x) 
    { 
     if(length(replacement) > 0) 
     { 
      gsub(pattern, replacement, x, fixed = TRUE) 
     } else x 
    }, 
    pattern = "PLACEHOLDER", 
    replacement = regmatches(original_code, function_content), 
    x = copy, 
    USE.NAMES = FALSE 
)) 

#Write back to your source file 
#writeLines(fixed_code, "source_file_fixed.R") 
+0

बहुत बहुत धन्यवाद! मैं वास्तव में इसकी प्रशंसा करता हूँ। Kohske 'codetools' के साथ एक शानदार समाधान के साथ आया है और मुझे एक [पुल अनुरोध] (https://github.com/kohske/formatR/commit/a2692d59f17ac9106e43f564857bc43d728fde6b) जिथब पर भेजा है। यही वह समाधान है जिसे मैं ढूंढ रहा था। –

+0

वाह। Kohske का समाधान अच्छा लग रहा है। और कोड चलना एक regex विधि से अधिक मजबूत होने के लिए बाध्य है। कृपया मेरे जवाब को "नियमित अभिव्यक्तियों का प्यारा डेमो" दें। –

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

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