वास्तव में बुराई बुराई क्यों है?


141

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

उदाहरण के लिए, मैं GOTOप्रक्रियात्मक प्रोग्रामिंग की समस्याओं को जानता हूं (कार्यक्रमों को अपठनीय और बनाए रखने में कठिन बनाता है, सुरक्षा समस्याओं को खोजने के लिए कठिन बनाता है, आदि), लेकिन मैंने कभी इसके खिलाफ तर्क नहीं देखा है eval

दिलचस्प बात GOTOयह है कि निरंतरता के खिलाफ एक ही तर्क मान्य होना चाहिए, लेकिन मैं देख रहा हूं कि स्कीमर्स, उदाहरण के लिए, यह नहीं कहेंगे कि निरंतरता "बुराई" है - आपको उनका उपयोग करते समय बस सावधान रहना चाहिए। वे evalनिरंतरता का उपयोग करके कोड की तुलना में कोड का उपयोग करने की अधिक संभावना रखते हैं (जहां तक ​​मैं देख सकता हूं - मैं गलत हो सकता है)।


5
eval बुराई नहीं है, लेकिन बुराई वही है जो eval करती है
अनुराग

9
@यर - मुझे लगता है कि आपकी टिप्पणी एक बहुत ही प्रेषण-वस्तु-केंद्रित विश्व दृष्टिकोण को इंगित करती है। यह संभवतः अधिकांश भाषाओं के लिए मान्य है, लेकिन कॉमन लिस्प में भिन्न होगा, जहां विधियां कक्षाओं से संबंधित नहीं हैं और क्लूजुर में भी भिन्न हैं, जहां कक्षाएं केवल जावा इंटरॉप फ़ंक्शन के माध्यम से समर्थित हैं। जे ने इस प्रश्न को स्कीम के रूप में टैग किया, जिसमें कक्षाओं या विधियों की कोई अंतर्निहित धारणा नहीं है (ओओ के विभिन्न रूप पुस्तकालय के रूप में उपलब्ध हैं)।
ज़क

3
@Zak, आप सही हैं, मैं केवल उन भाषाओं को जानता हूं जिन्हें मैं जानता हूं, लेकिन भले ही आप स्टाइल्स का उपयोग किए बिना एक वर्ड डॉक्यूमेंट के साथ काम कर रहे हों आप DRY नहीं हैं। मेरा कहना था कि प्रौद्योगिकी का उपयोग खुद को दोहराना नहीं है। OO सार्वभौमिक नहीं है, सच है ...
Dan Rosenstark

4
मैंने इस सवाल पर क्लोजर टैग जोड़ने की स्वतंत्रता ली, क्योंकि मेरा मानना ​​है कि क्लोजर उपयोगकर्ताओं को यहां पोस्ट किए गए उत्कृष्ट उत्तरों के संपर्क में आने से फायदा हो सकता है।
माइकल मार्कीज

... ठीक है, क्लोजर के लिए, कम से कम एक अतिरिक्त कारण लागू होता है: आप क्लोजरस्क्रिप्ट और इसके डेरिवेटिव के साथ संगतता खो देते हैं।
चार्ल्स डफी

जवाबों:


148

ऐसे कई कारण हैं, जिनका उपयोग नहीं करना चाहिए EVAL

शुरुआती लोगों का मुख्य कारण है: आपको इसकी आवश्यकता नहीं है।

उदाहरण (सामान्य लिस्प मानते हुए):

विभिन्न ऑपरेटरों के साथ एक अभिव्यक्ति का मूल्यांकन करें:

(let ((ops '(+ *)))
  (dolist (op ops)
    (print (eval (list op 1 2 3)))))

यह बेहतर लिखा है:

(let ((ops '(+ *)))
  (dolist (op ops)
    (print (funcall op 1 2 3))))

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

मैक्रों के साथ भी यही समस्या है। अक्सर शुरुआती मैक्रोज़ लिखते हैं, जहां उन्हें फ़ंक्शंस लिखना चाहिए - यह नहीं समझना कि मैक्रोज़ वास्तव में क्या हैं और यह नहीं समझना कि एक फ़ंक्शन पहले से ही काम करता है।

यह नौकरी का उपयोग करने के लिए अक्सर गलत उपकरण है EVALऔर यह अक्सर इंगित करता है कि शुरुआती सामान्य लिस्प मूल्यांकन नियमों को नहीं समझता है।

यदि आपको लगता है कि आपको जरूरत है EVAL, तो जांचें कि क्या कुछ पसंद है FUNCALL, REDUCEया APPLYइसके बजाय इसका उपयोग किया जा सकता है।

  • FUNCALL - तर्कों के साथ एक फ़ंक्शन को कॉल करें: (funcall '+ 1 2 3)
  • REDUCE - मानों की सूची पर एक फ़ंक्शन को कॉल करें और परिणाम गठबंधन करें: (reduce '+ '(1 2 3))
  • APPLY- एक फ़ंक्शन को एक सूची के साथ तर्कों के रूप में कॉल करें (apply '+ '(1 2 3)):।

प्रश्न: क्या मुझे वास्तव में eval की आवश्यकता है या क्या संकलक / मूल्यांकनकर्ता पहले से ही मैं वास्तव में क्या चाहता हूं?

EVALथोड़ा और अधिक उन्नत उपयोगकर्ताओं से बचने के मुख्य कारण :

  • आप यह सुनिश्चित करना चाहते हैं कि आपका कोड संकलित किया गया है, क्योंकि कंपाइलर कई समस्याओं के लिए कोड की जांच कर सकता है और तेजी से कोड उत्पन्न करता है, कभी-कभी बहुत अधिक (यह कारक 1000; ;-)) से तेज कोड होता है।

  • कोड जो निर्माण किया गया है और मूल्यांकन करने की आवश्यकता है, उसे जल्द से जल्द संकलित नहीं किया जा सकता है।

  • उपयोगकर्ता इनपुट का मनमाना उपयोग सुरक्षा समस्याओं को खोलता है

  • मूल्यांकन के कुछ उपयोग EVALगलत समय पर हो सकते हैं और बिल्ड समस्याएं पैदा कर सकते हैं

सरलीकृत उदाहरण के साथ अंतिम बिंदु समझाने के लिए:

(defmacro foo (a b)
  (list (if (eql a 3) 'sin 'cos) b))

इसलिए, मैं एक मैक्रो लिखना चाहता हूं जो पहले पैरामीटर के आधार पर SINया तो उपयोग करता है या COS

(foo 3 4)करता है (sin 4)और(foo 1 4) करता है (cos 4)

अब हमारे पास हो सकता है:

(foo (+ 2 1) 4)

यह वांछित परिणाम नहीं देता है।

एक तो FOOचर को चिह्नित करके मैक्रो की मरम्मत करना चाहता है :

(defmacro foo (a b)
  (list (if (eql (eval a) 3) 'sin 'cos) b))

(foo (+ 2 1) 4)

लेकिन फिर भी यह काम नहीं करता है:

(defun bar (a b)
  (foo a b))

चर का मान अभी संकलन समय पर ज्ञात नहीं है।

बचने का एक सामान्य महत्वपूर्ण कारण EVAL: इसका उपयोग अक्सर बदसूरत हैक्स के लिए किया जाता है।


3
धन्यवाद! मैं सिर्फ अंतिम बिंदु (गलत समय पर मूल्यांकन?) को समझ नहीं पाया - क्या आपने थोड़ा सा विस्तार किया है?
जेई

41
+1 जैसा कि यह वास्तविक उत्तर है - लोग evalकेवल इसलिए वापस लौट जाते हैं क्योंकि वे नहीं जानते कि कोई विशिष्ट भाषा या लाइब्रेरी सुविधा है जो वे करना चाहते हैं। जेएस से समान उदाहरण: मैं एक गतिशील नाम का उपयोग करके किसी ऑब्जेक्ट से संपत्ति प्राप्त करना चाहता हूं, इसलिए मैं लिखता हूं: eval("obj.+" + propName)जब मैं लिख सकता था obj[propName]
डैनियल ईयरविकर

मैं देख रहा हूं कि अब आपका क्या मतलब है, रेनर! Thansk!
जे

@ डैनियल "obj.+":? अंतिम बार मैंने जाँच की, +जेएस में डॉट-रेफरेंस का उपयोग करते समय मान्य नहीं है।
हैलो71

2
@ डैनियल का मतलब संभवतः निष्कासन ("obj।" + प्रोपनाम) है जो उम्मीद के मुताबिक काम करना चाहिए।
क्लेज

41

eval(किसी भी भाषा में) उसी तरह से बुराई नहीं है जिस तरह से एक जंजीर बुराई नहीं है। यह एक उपकरण है। यह एक शक्तिशाली उपकरण होता है, जिसका दुरुपयोग होने पर, अंग और विरूपित (गंभीर रूप से बोलना) गंभीर हो सकते हैं, लेकिन प्रोग्रामर के टूलबॉक्स में कई उपकरणों के लिए भी यही कहा जा सकता है:

  • goto और मित्र
  • लॉक-आधारित थ्रेडिंग
  • निरंतरता
  • मैक्रोज़ (स्वच्छ या अन्य)
  • संकेत
  • पुनः आरंभ करने योग्य अपवाद
  • स्व-संशोधित कोड
  • ... और हजारों की डाली।

यदि आप खुद को इनमें से किसी भी शक्तिशाली, संभावित खतरनाक उपकरण का उपयोग करते हुए पाते हैं, तो अपने आप से तीन बार पूछें "क्यों?" एक श्रृंखला में। उदाहरण के लिए:

"मुझे क्यों उपयोग करना है eval?" "फू के कारण।" "फू क्यों जरूरी है?" "इसलिये ..."

यदि आप उस श्रृंखला के अंत में आते हैं और उपकरण अभी भी ऐसा लगता है कि यह करना सही है, तो इसे करें। इसमें से नर्क का दस्तावेज। इसमें से नर्क का परीक्षण करें। बार-बार शुद्धता और सुरक्षा की जांच करें। लेकिन कर लो।


धन्यवाद - यही है कि मैंने पहले भी स्पष्ट रूप से सुना ("अपने आप से पूछें"), लेकिन मैंने अभी तक कभी नहीं सुना या पढ़ा कि संभावित समस्याएं क्या हैं। मैं अब यहां के उत्तरों से देखता हूं कि वे क्या हैं (सुरक्षा और प्रदर्शन की समस्याएं)।
जय

8
और कोड पठनीयता। Eval पूरी तरह से कोड के प्रवाह को खराब कर सकता है और इसे समझ से बाहर कर सकता है।
मेरे सही विकल्प

मुझे समझ नहीं आ रहा है कि "लॉक-थ्रेडिंग" [sic] आपकी सूची में क्यों है। संगामिति के ऐसे रूप हैं जिनमें ताले शामिल नहीं हैं, और ताले के साथ समस्याएं आम तौर पर अच्छी तरह से ज्ञात हैं, लेकिन मैंने कभी किसी को ताले का "बुराई" के रूप में वर्णन करने के बारे में नहीं सुना है।
1948 में asikikau

4
asveikau: लॉक-आधारित थ्रेडिंग सही तरीके से प्राप्त करने के लिए बेहद मुश्किल है (मुझे लगता है कि लॉक का उपयोग करके उत्पादन कोड का 99.44% खराब है)। यह रचना नहीं है। यह आपके "मल्टी-थ्रेडेड" कोड को सीरियल कोड में बदलने का खतरा है। (इसके लिए सही करने से कोड धीमा हो जाता है और इसके बजाय फूला हुआ हो जाता है।) एसटीएम या अभिनेता मॉडल की तरह लॉक-आधारित थ्रेडिंग के लिए अच्छे विकल्प हैं, जो कि इसका उपयोग किसी भी चीज में करता है लेकिन सबसे निचले स्तर का कोड बुराई है।
मेरी सही जानकारी

"क्यों चेन" :) 3 चरणों के बाद रोकना सुनिश्चित करें कि यह चोट पहुंचा सकता है।
szymanowski

27

Eval ठीक है, जब तक आप जानते हैं कि वास्तव में क्या चल रहा है। इसमें जाने वाले किसी भी उपयोगकर्ता इनपुट की जाँच की जानी चाहिए और उसे सत्यापित किया जाना चाहिए। यदि आप नहीं जानते कि 100% कैसे सुनिश्चित हो, तो ऐसा न करें।

मूल रूप से, उपयोगकर्ता प्रश्न में भाषा के लिए किसी भी कोड में टाइप कर सकता है, और यह निष्पादित करेगा। आप अपने लिए कल्पना कर सकते हैं कि वह कितना नुकसान कर सकता है।


1
इसलिए यदि मैं वास्तव में उपयोगकर्ता इनपुट पर आधारित एस-एक्सप्रेशंस उत्पन्न कर रहा हूं जो कि एक एल्गोरिथ्म का उपयोग करता है जो सीधे उपयोगकर्ता इनपुट की नकल नहीं करेगा, और यदि मैक्रोज़ या अन्य तकनीकों का उपयोग करने की तुलना में कुछ विशिष्ट स्थिति में यह आसान और स्पष्ट है, तो मुझे लगता है कि कुछ भी नहीं है "बुराई" " इसके बारे में? दूसरे शब्दों में, eval के साथ एकमात्र समस्याएं SQL क्वेरी और अन्य तकनीकों के साथ समान हैं जो सीधे उपयोगकर्ता इनपुट का उपयोग करती हैं?
जे

10
इसे "बुराई" कहने का कारण यह है कि इसे गलत करना अन्य चीजों को गलत करने की तुलना में बहुत बुरा है। और जैसा कि हम जानते हैं, newbies सामान गलत करेंगे।
Tor Valamo

3
मैं यह नहीं कहूंगा कि सभी परिस्थितियों में इसे विकसित करने से पहले कोड को मान्य किया जाना चाहिए। उदाहरण के लिए एक साधारण REPL को लागू करते समय, आप शायद इनपुट को अनियंत्रित में फीड करेंगे और यह समस्या नहीं होगी (बेशक जब वेब-आधारित REPL लिख रहा हो तो आपको सैंडबॉक्स की आवश्यकता होगी, लेकिन यह सामान्य बात नहीं है CLI-REPLs जो उपयोगकर्ता के सिस्टम पर चलते हैं)।
sepp2k

1
जैसा कि मैंने कहा, आपको यह जानना होगा कि जब आप भोजन करते हैं तो क्या होता है। यदि इसका मतलब है कि "यह सैंडबॉक्स की सीमा के भीतर कुछ कमांड निष्पादित करेगा", तो इसका मतलब है। ;)
Tor Valamo

@TorValamo ने कभी जेल ब्रेक के बारे में सुना?
Locc Faure-Lacroix

21

"मुझे कब उपयोग करना चाहिए eval?" एक बेहतर सवाल हो सकता है।

संक्षिप्त उत्तर है "जब आपका प्रोग्राम रनटाइम में एक और प्रोग्राम लिखने का इरादा रखता है, और फिर इसे चलाएं"। जेनेटिक प्रोग्रामिंग एक ऐसी स्थिति का एक उदाहरण है जहां इसका उपयोग करने की संभावना है eval


14

IMO, यह प्रश्न LISP के लिए विशिष्ट नहीं है । यहाँ PHP के लिए एक ही प्रश्न पर एक उत्तर दिया गया है, और यह LISP, रूबी और अन्य भाषाओं पर लागू होता है जिसमें एक साक्ष्य है:

Eval () के साथ मुख्य समस्याएं हैं:

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

Eval () के वास्तविक उपयोग के साथ मुख्य समस्या केवल एक है:

  • अनुभवहीन डेवलपर्स जो इसे पर्याप्त विचार के बिना उपयोग करते हैं।

यहां से ले गए ।

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

फिर LISP में उस संदर्भ से संबंधित कुछ समस्या है जिसमें eval चलाया जाता है, इसलिए अविश्वसनीय कोड अधिक चीजों तक पहुंच प्राप्त कर सकता है; यह समस्या वैसे भी आम है।


3
EVAL के साथ "बुराई इनपुट" समस्या केवल गैर-लिस्प भाषाओं को प्रभावित करती है, क्योंकि उन भाषाओं में, eval () आम तौर पर एक स्ट्रिंग तर्क लेती है, और उपयोगकर्ता के इनपुट में आमतौर पर स्प्लिस किया जाता है। उपयोगकर्ता अपने इनपुट में एक उद्धरण शामिल कर सकते हैं और इसमें बच सकते हैं। उत्पन्न कोड। लेकिन लिस्प में, EVAL का तर्क एक स्ट्रिंग नहीं है, और उपयोगकर्ता इनपुट कोड में बच नहीं सकते हैं जब तक कि आप बिल्कुल लापरवाह न हों (जैसा कि आपने एस-एक्सप्रेशन बनाने के लिए READ-FROM-STRING के साथ इनपुट पार्स किया, जिसे आप तब शामिल करते हैं इसे उद्धृत किए बिना EVAL कोड। यदि आप इसे उद्धृत करते हैं, तो उद्धरण से बचने का कोई तरीका नहीं है)।
थ्रू अवे अकाउंट

12

कई शानदार जवाब दिए गए हैं, लेकिन यहां मैथ्यू फ्लैट से एक और लिया गया है, जो रैकेट के कार्यान्वयनकर्ताओं में से एक है:

http://blog.racket-lang.org/2011/10/on-eval-in-dynamic-languages-generally.html

वह कई ऐसे बिंदु बनाता है जो पहले से ही कवर किए गए हैं, लेकिन कुछ लोगों को उसका फिर भी दिलचस्प लग सकता है।

सारांश: जिस संदर्भ में इसका उपयोग किया जाता है वह निष्कासन के परिणाम को प्रभावित करता है लेकिन अक्सर प्रोग्रामर द्वारा इस पर विचार नहीं किया जाता है, जिससे अप्रत्याशित परिणाम प्राप्त होते हैं।


11

विहित उत्तर दूर रहना है। जो मुझे अजीब लगता है, क्योंकि यह एक आदिम है, और सात आदिम (दूसरों के विपक्ष, कार, सीडीआर, अगर, ईक और बोली) में है, तो यह दूर और कम से कम उपयोग और प्यार प्राप्त करता है।

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

तो मैं eval का उपयोग कब करूं? एक सामान्य उपयोग मूल्यांकन करके अपने REPL के भीतर एक REPL है (loop (print (eval (read))))। हर कोई उस उपयोग के साथ ठीक है।

लेकिन आप मैक्रोज़ के संदर्भ में फ़ंक्शंस को भी परिभाषित कर सकते हैं, जिन्हें मूल्यांकन के बाद बैकॉक के साथ eval के संयोजन द्वारा मूल्यांकन किया जाएगा । तुम जाओ

(eval `(macro ,arg0 ,arg1 ,arg2))))

और यह आपके लिए संदर्भ को मार देगा।

Swank (emacs कीचड़ के लिए) इन मामलों से भरा है। वे इस तरह दिखते हैं:

(defun toggle-trace-aux (fspec &rest args)
  (cond ((member fspec (eval '(trace)) :test #'equal)
         (eval `(untrace ,fspec))
         (format nil "~S is now untraced." fspec))
        (t
         (eval `(trace ,@(if args `(:encapsulate nil) (list)) ,fspec ,@args))
         (format nil "~S is now traced." fspec))))

मुझे नहीं लगता कि यह एक गंदी हैक है। मैक्रो में फ़ंक्शंस को पुन: स्थापित करने के लिए मैं हर समय इसका उपयोग करता हूं।


1
आप कर्नेल भाषा की जांच कर सकते हैं;)
आर्टेमस्टर

7

लिस्प eval पर अंक की एक और जोड़ी:

  • यह आपके स्थानीय संदर्भ को खोते हुए वैश्विक पर्यावरण के तहत मूल्यांकन करता है।
  • कभी-कभी आपको eval का उपयोग करने के लिए लुभाया जा सकता है, जब आप वास्तव में रीड-मैक्रो '#' का उपयोग करने के लिए थे। जो समय-समय पर मूल्यांकन करता है।

मैं समझता हूं कि कॉमन लिस्प और स्कीम दोनों के लिए वैश्विक एनवी का उपयोग सही है; क्या यह क्लोजर के लिए भी सही है?
जे

2
स्कीम में (कम से कम R7RS के लिए, शायद R6RS के लिए भी) आपको एक वातावरण को खाली करने के लिए पास करना होगा।
सीएसएल

4

गोटो "नियम" की तरह: यदि आप नहीं जानते कि आप क्या कर रहे हैं, तो आप गड़बड़ कर सकते हैं।

केवल ज्ञात और सुरक्षित डेटा से कुछ बनाने के अलावा, समस्या यह है कि कुछ भाषाएं / कार्यान्वयन कोड को पर्याप्त रूप से अनुकूलित नहीं कर सकते हैं। आप अंदर व्याख्या कोड के साथ समाप्त कर सकते हैं eval


उस नियम का GOTO के साथ क्या संबंध है? क्या किसी भी प्रोग्रामिंग भाषा में कोई सुविधा है जिसके साथ आप कोई गड़बड़ नहीं कर सकते ?
केन

2
@Ken: कोई GOTO नियम नहीं है, इसलिए मेरे उत्तर में उद्धरण चिह्न हैं। ऐसे लोगों के लिए सिर्फ एक हठधर्मिता है जो अपने लिए सोचने से डरते हैं। Eval के लिए भी। मुझे याद है कि कुछ पर्ल लिपि को तेजी से निकालकर तेजी से इस्तेमाल किया गया था। यह आपके टूलबॉक्स में एक उपकरण है। जब अन्य भाषा के निर्माण आसान / बेहतर होते हैं, तो न्यूबल्स अक्सर eval का उपयोग करते हैं। लेकिन यह पूरी तरह से सिर्फ शांत होने से बचने और हठधर्मी लोगों को खुश करने के लिए?
स्टेक

4

Eval सिर्फ असुरक्षित है। उदाहरण के लिए आपके पास निम्नलिखित कोड हैं:

eval('
hello('.$_GET['user'].');
');

अब उपयोगकर्ता आपकी साइट पर आता है और url http://example.com/file.php?user= ) में प्रवेश करता है ; $ is_admin = true; echo (

फिर परिणामी कोड होगा:

hello();$is_admin=true;echo();

6
वह Lisp के बारे में बात कर रहा था php नहीं
fmsf

4
@fmsf वह विशेष रूप से लिस्प के बारे में बात कर रहा था लेकिन आम तौर पर evalकिसी भी भाषा में जिसके बारे में है।
14

4
@fmsf - यह वास्तव में एक भाषा-स्वतंत्र प्रश्न है। यह स्टैटिक संकलित भाषाओं पर भी लागू होता है क्योंकि वे रनटाइम के समय कंपाइलर को कॉल करके ईवैल का अनुकरण कर सकते हैं।
डैनियल ईयरविकर

1
उस मामले में भाषा एक डुप्लिकेट है। मैंने बहुत से इस तरह से देखा है यहाँ एक।
fmsf

9
PHP eval, Lisp eval की तरह नहीं है। देखो, यह एक चरित्र स्ट्रिंग पर काम करता है, और URL में शोषण एक पाठीय कोष्ठक को बंद करने और एक दूसरे को खोलने में सक्षम होने पर निर्भर करता है। लिस्प का निष्कासन इस तरह के सामान के लिए अतिसंवेदनशील नहीं है। आप एक नेटवर्क से इनपुट के रूप में आने वाले डेटा को निकाल सकते हैं, यदि आप इसे ठीक से सैंडबॉक्स करते हैं (और ऐसा करने के लिए संरचना चलना आसान है)।
कज़

2

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

आपको इसका उपयोग कब करना चाहिए? जब भी आपको कुछ संकलित करने की आवश्यकता होती है, तो आमतौर पर एक प्रोग्राम जो स्वीकार करता है, रनटाइम पर मनमाना कोड को उत्पन्न या संशोधित करता है

आपको इसका उपयोग कब नहीं करना चाहिए अन्य सभी मामले।

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

हाँ, लेकिन अगर मैं एक शुरुआती हूँ तो मुझे कैसे पता चलेगा कि मुझे इसका उपयोग करना चाहिए? हमेशा कार्यों के साथ आपको जो आवश्यक है उसे लागू करने का प्रयास करें। अगर वह काम नहीं करता है, तो मैक्रोज़ जोड़ें। अगर वह अभी भी काम नहीं करता है, तो eval!

इन नियमों का पालन करें और आप कभी भी बुराई के साथ बुराई नहीं करेंगे :)


0

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

(eval (read-line))

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.