2010-07-21 11 views
6

आप में से उन लोगों के लिए जो डी स्ट्रिंग मिक्सिन से परिचित नहीं हैं, वे मूल रूप से संकलित-समय evals हैं। आप किसी भी संकलन समय स्ट्रिंग (चाहे एक शाब्दिक या टेम्पलेट मेटाप्रोग्रामिंग द्वारा उत्पन्न या समय समारोह मूल्यांकन संकलित) ले सकते हैं और इसे कोड के रूप में संकलित कर सकते हैं। यदि आप एक साधारण स्ट्रिंग अक्षर का उपयोग करते हैं, तो यह मूल रूप से संकलक-स्वचालित प्रति-पेस्ट है।कोड के लिए डी स्ट्रिंग mixins का उपयोग कर एक विरोधी पैटर्न का पुन: उपयोग कर रहा है?

क्या आप इसे सरल कोड पुन: उपयोग के साधन के रूप में अक्षर के स्ट्रिंग मिश्रणों का उपयोग करने के लिए एक एंटीपार्टर्न मानेंगे जहां फैक्टरिंग के अन्य तरीके काफी फिट नहीं हैं? एक तरफ, यह मूल रूप से संकलक-स्वचालित शाब्दिक प्रति-और-पेस्ट है, जिसका अर्थ है कि उदाहरणों में मिश्रित होने के बाद एक-दूसरे के साथ कुछ भी नहीं करना पड़ता है। खराब चीजें घटित होंगी (हालांकि संकलन समय पर, रनटाइम पर नहीं) यदि स्ट्रिंग मिश्रित में एक प्रतीक मिश्रित क्षेत्र में एक प्रतीक के साथ टकराता है। यह अपेक्षाकृत असंभव है कि, उदाहरण के लिए, एक स्ट्रिंग को उस फ़ंक्शन के बीच में मिलाएं जो काम करेगा और केवल तभी होगा जब दायरे में चर को एक निश्चित सम्मेलन के अनुसार नामित किया गया हो। मिक्स्ड वेरिएबल्स भी घोषित कर सकते हैं कि बाहरी स्कॉप्स तब फिट बैठ सकते हैं जब वे फिट दिखाई देते हैं।

दूसरी ओर, क्योंकि कॉपी-एंड-पेस्ट कंपाइलर स्वचालित है, स्रोत स्तर पर प्रश्न में कोड के लिए सत्य का एक बिंदु है और यदि इसे संशोधित करने की आवश्यकता है, तो इसे केवल संशोधित करने की आवश्यकता है एक स्थान पर, और सब कुछ सिंक में रहता है। स्ट्रिंग मिक्सर भी पुन: उपयोग करने वाले कोड को बहुत सरल बनाते हैं जो कि किसी अन्य तरीके से कारक करना बहुत कठिन होता है और अन्यथा मैन्युअल रूप से कट-एंड-पेस्ट होने की बहुत अधिक संभावना होती है।

उत्तर

9

आपके द्वारा उठाए गए सभी आलोचनाएं सच हैं।

भले ही, यह मैन्युअल कॉपीपेस्ट से अभी भी बेहतर है।

असल में, मेरे पास मेरे टूल्स लाइब्रेरी, स्ट्रिंग टेबल विस्तार में कुछ समान चल रहा है। एक पथ ट्रेसर के एक गतिशील मान कार्यान्वयन से उदाहरण कोड,:

T to(T)() { 
    static if (!is(T == Scope)) { 
     T value; 
     if (flatType == FlatType.ScopeValue) value = sr.value().to!(T); 
    } 
    const string Table = ` 
       | bool   | int   | string    | float | Scope 
     -----------+---------------+-------------+----------------------+---------+---------- 
     Boolean | b    | b   | b?q{true}p:q{false}p | ø  | ø 
     Integer | i != 0  | i   | Format(i)   | i  | ø 
     String  | s == q{true}p | atoi(s)  | s     | atof(s) | ø 
     Float  | ø    | cast(int) f | Format(f)   | f  | ø 
     ScopeRef | !!sr   | ø   | (sr?sr.fqn:q{(null:r)}p) | ø | sr 
     ScopeValue | value   | value  | value    | value | sr`; 
    mixin(ctTableUnrollColMajor(Table, 
     `static if (is(T == $COL)) 
     switch (flatType) { 
      $BODY 
      default: throw new Exception(Format("Invalid type: ", flatType)); 
     } 
     else `, 
     `case FlatType.$ROW: 
     static if (q{$CELL}p == "ø") 
      throw new Exception(q{Cannot convert $ROW to $COL: }p~to!(string)~q{! }p); 
     else return $CELL; 
     ` 
    ).litstring_expand() ~ `static assert(false, "Unsupported type: "~T.stringof); `); 
    } 

मुझे यकीन है कि यह देखना आसान है कर रहा हूँ क्या एक भयानक, नेस्ट आईएफएस और मामले बयान है कि स्ट्रिंग mixins के बिना होगा की अनावश्यक गंदगी - इस तरह से, सभी कुरूपता नीचे केंद्रित है, और वास्तविक कार्य फ़ंक्शन के एक नज़र में पढ़ने के लिए आसान है।

+0

* स्नीफ * मैं दिल तुम, जीप। यह वास्तव में आपके अधिक भयानक विचारों में से एक है। –

+0

प्रत्येक विश्वसनीय अर्ध-साफ चाल जैसे कि तीन या चार विचार हैं जो केवल सादे _horrible_ हैं - जैसे कि सीटीएफई टेक्स्ट-आधारित राज्य मशीन ग्राफ़ पार्सर टूल्स में गहरी दफन की गई है :) – FeepingCreature

2

अन्य, यदि आप कर सकते हैं तो अधिक सुरुचिपूर्ण समाधान बेहतर हो सकते हैं, स्ट्रिंग मिश्रित बेहद उपयोगी हो सकते हैं। वे दोनों कोड पुन: उपयोग और कोड पीढ़ी के लिए अनुमति देते हैं। वे संकलन समय पर जांच कर रहे हैं। परिणाम जो कोड बिल्कुल वैसा ही है जैसा आपने इसे हाथ से लिखा है, इसलिए यदि आप इसे हाथ से लिख चुके हैं तो यह कम सुरक्षित नहीं है।

स्ट्रिंग मिश्रणों के साथ समस्या यह है कि हाथ में लिखे गए कोड से उन्हें नियंत्रित करना कठिन होता है, यह समझ में आता है कि यह आपके स्रोत में शारीरिक रूप से नहीं रखा गया है, साथ ही रेखा संख्या स्पष्ट रूप से त्रुटियों के लिए पता लगाने योग्य है, और यह हो सकता है डीबग करने के लिए कठिन है। उदाहरण के लिए, एक स्ट्रिंग mixin साथ नमस्ते दुनिया ले:

import std.stdio; 

void main() 
{ 
    mixin(hello()); 
} 

string hello() 
{ 
    return " 
    writeln(\"hello world\"); 
"; 
} 

हम writeln() के बाद अर्धविराम दूर करने के लिए थे, तो त्रुटि हमारे पास

d.d(7): found 'EOF' when expecting ';' following statement 

mixin लाइन 5 पर किया जाता है होगा। रेखा 7 एक खाली रेखा है। तो, रेखा संख्या यहां सीमित उपयोगिता है। अब, यह मिश्रण इतना छोटा है कि हम इसे एक पंक्ति पर डाल सकते थे और यह कहने के लिए प्राप्त कर सकते थे कि त्रुटि मिश्रण के समान रेखा पर थी, लेकिन अधिक जटिल मिश्रित के साथ, यह स्पष्ट रूप से काम नहीं करेगा। तो, एक स्ट्रिंग मिश्रण का उपयोग करके, यह पता लगाने की आपकी क्षमता है कि त्रुटि कहां खराब है।यदि कोड सीटीएफई का उपयोग करके जेनरेट किया गया है, तो यह पता लगाने के लिए कि यह क्या गलत है, यह पता लगाने के लिए यह भी उतना ही मुश्किल हो जाएगा कि कोड कैसा दिखता है। यह पता लगाने की तरह है कि सी-स्टाइल मैक्रो किस कोड में बदल जाता है, सिवाय इसके कि यह बदतर हो सकता है क्योंकि उन्हें सीधे प्रतिस्थापन के बजाय उत्पन्न किया जा सकता है। हालांकि, वे स्पष्ट रूप से उन्हें कहने के अलावा उन्हें प्रतिस्थापित नहीं करते हैं, इसलिए वे सी-शैली मैक्रोज़ से कहीं अधिक सुरक्षित हैं।

स्ट्रिंग मिश्रण पूरी तरह से सुरक्षित हैं, और उनके साथ विशेष रूप से कुछ भी गलत नहीं है, लेकिन वे कुछ तरीकों से रखरखाव को कठिन बनाते हैं। इसी तरह के हाथ से लिखित कोड डीबग करना आसान होगा। हालांकि, स्ट्रिंग मिश्रित पर्याप्त शक्तिशाली हैं कि वे आपके लिए बहुत सी कोड जनरेशन कर सकते हैं और आपको उस भावना में बहुत से रखरखाव लागतों को बचा सकते हैं, और वे आपको कोड का फिर से उपयोग करने की अनुमति देते हैं, जो एक बड़ा रखरखाव लाभ भी हो सकता है।

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

व्यक्तिगत रूप से, मुझे लगता है कि यदि आप कोड उत्पन्न करना चाहते हैं तो वे शानदार हैं, स्वयं को उस कोड को हाथ से लिखने का प्रयास सहेजना, और संभवतः विभिन्न स्थितियों के लिए सही कोड उत्पन्न करना आसान बनाना और आपके जैसे नई बग बनाने के जोखिम से बचने से आपने उन सभी स्थानों में खुद को लिखा होगा जहां आपने मिश्रण का उपयोग किया था। यह फंक्शन कॉल की लागत या सिंगल-विरासत की सीमाओं के साथ मुद्दों या किसी भी चीज को कॉल या फिर विरासत को कड़ी मेहनत करके कोड का पुन: उपयोग करने के बारे में चिंता किए बिना कोड का पुन: उपयोग करने के तरीकों में से एक है। आप बस प्रत्येक स्थान पर कोड को प्रतिलिपि बनाकर चिपका रहे हैं जिससे यह सुनिश्चित हो जाता है कि यदि आप कोड बदलते हैं, तो परिवर्तनों को ठीक से चिपकाया जाएगा, बिना आपको उन सभी को ट्रैक करने के बारे में चिंता किए बिना, जैसे कि आपके पास हाथ की प्रतिलिपि थी और चिपकाया।

तो, जहां उचित हो वहां स्ट्रिंग मिश्रित का उपयोग करें, और यदि संभव नहीं है तो इसका उपयोग न करना सबसे अच्छा है, लेकिन इनका उपयोग करने में वास्तव में कुछ भी गलत नहीं है।

+0

मैंने पाया कि लाइन नंबर को सुधारने का एकमात्र तरीका समस्या स्ट्रिंग mixin स्रोत में '# लाइन' निर्देश डालने के लिए था। इस तरह, त्रुटियां आमतौर पर मोटे तौर पर सही स्थान पर गिरती हैं; एक पूर्ण और पूरी तरह से दुःस्वप्न से कम सीटीएफई-जेनरेटेड स्ट्रिंग मिक्सर से निर्मित एक पूरी बाध्यकारी लाइब्रेरी डिबगिंग की गई। –

+0

आप जानते हैं कि न्यूलाइन को हटाने के लिए आप केवल एक सीटीएफई फ़ंक्शन लिख सकते हैं। ^^ – FeepingCreature

+1

@FeepingCreature LOL। प्यारा। इससे त्रुटि संदेश में रेखा के साथ मदद मिलेगी जो स्ट्रिंग को उस फ़ाइल में इंगित करती है जिस पर स्ट्रिंग को बाद में फ़ाइल में त्रुटि संदेश मिलते हैं, लेकिन यह मिश्रण में त्रुटि को खोजने में मदद नहीं करेगा। बेशक, चूंकि आपको यह भी जरूरी नहीं है कि कोड किस तरह मिश्रित हो रहा है, यह जानकर कि कौन सी रेखा संख्या खराब है, यह आवश्यक रूप से आपकी मदद नहीं करता है। मुझे लगता है कि कहानी का नैतिक यह है कि काम करने वाले स्ट्रिंग मिश्रक बहुत अच्छे हैं, लेकिन छोटी गाड़ी को ठीक करने के लिए दर्द हो सकता है। –

1

स्ट्रिंग मिक्सिन गोटो की तरह है: जहां भी संभव हो वहां से बचा जाना चाहिए और जहां भी आवश्यक हो वहां उपयोग किया जाना चाहिए।

+0

उसमें कुछ सच्चाई है, लेकिन मैं आम तौर पर प्लेग की तरह गेटो से बचता हूं, जबकि मैं विभिन्न परिस्थितियों में स्ट्रिंग मिश्रक का उपयोग करने के लिए तैयार हूं। अब, यदि स्ट्रिंग मिश्रक की तुलना में बेहतर समाधान हैं, तो मैं निश्चित रूप से इसे ले जाऊंगा, लेकिन मैं अपने कोड में स्ट्रिंग मिश्रित रखने के लिए पूरी तरह से तैयार हूं, जबकि मैं अपने कोड में वास्तव में गोटो लगाने से पहले कठिन और निश्चित रूप से पुनर्विचार करता हूं। –

+0

@ जोनाथन एम डेविस: यह मुझे लगता है जैसे आप 'गोटो' का उपयोग करने के लिए अधिक अनिच्छुक हैं। ओटीओएच बहुत कम मामले हैं जहां आपको लेबल में ब्रेक और जारी रखने के साथ डी में 'गोटो' का उपयोग करना होगा। – BCS

+0

@ बीबीएसएस मैं अनिवार्य रूप से कभी भी किसी भी भाषा में गोटो का उपयोग नहीं करता जब तक कि मेरे पास आवश्यक प्रदर्शन प्राप्त करने के लिए कोई अन्य विकल्प न हो। मुझे वास्तव में लेबल जारी या लेबल ब्रेक पसंद नहीं है, लेकिन अगर मैं किसी विशेष स्थिति में अच्छी समझ में आया तो मैं उनका उपयोग करने के इच्छुक हूं। लेकिन सीधे गेटो? उसमें बहुत ज्यादा मौका नहीं है। जब तक आप * वास्तव में * प्रदर्शन की आवश्यकता नहीं है, हमेशा एक बेहतर तरीका है। तो, हाँ, ऐसा लगता है कि मैं आपके से गोटो का उपयोग करने के लिए अधिक अनिच्छुक हूं। –

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