2011-12-28 20 views
11

मैं एक ऐसे वेब ऐप से निपट रहा हूं जो घर से उगाए जाने वाले टेम्पलेटिंग सिस्टम का उपयोग करता है जो एचटीएमएल में पर्ल कोड को एम्बेड करने देता है। इन कथनों को eval EXPR का उपयोग कर रन-टाइम पर टेम्पलेट पार्सर द्वारा निष्पादित किया जाता है।eval के लिए तेज़ विकल्प?

यह बहुत लचीला है, लेकिन ये कथन हर जगह बिखरे हुए हैं, और लॉट निष्पादित किए गए हैं। eval EXPR (eval BLOCK के विपरीत) पर्ल को प्रत्येक बार दुभाषिया को आग लगाने की आवश्यकता होती है, और मेरी प्रोफाइलिंग से पता चलता है कि वे मंदी का एक महत्वपूर्ण स्रोत हैं।

एम्बेडेड पर्ल स्टेटमेंट्स में से कई बहुत ही सरल हैं।

<p>Welcome, <!--E: $user->query('name') -->. 

या::

<p>Ticket number <!--E: $user->generate_ticket_number() --> has been generated. 

है, वे सिर्फ वस्तु तरीकों कॉल कर रहे हैं उदाहरण के लिए, एक टेम्पलेट इस तरह एक लाइन हो सकता है। हालांकि, अधिक जटिल भी हैं।

मैं इसे अनुकूलित करने की उम्मीद कर रहा हूं, और अब तक दो विचार हैं, जिनमें से दोनों भयानक हैं। सबसे पहले USER:NAME और USER:GENERATETICKETNUMBER जैसे टोकन के साथ सरल कॉल को प्रतिस्थापित करने के लिए सभी टेम्पलेट्स को फिर से लिखना है, जिसे पार्सर तब स्कैन कर सकता है और उचित ऑब्जेक्ट विधि का आह्वान कर सकता है। लेकिन फिर HTML और पर्ल मिश्रण करने वाले टेम्पलेट्स से निपटने के बजाय, मेरे पास टेम्पलेट्स होंगे जो HTML, पर्ल और टोकन मिश्रण करते हैं।

दूसरा विचार एम्बेडेड पर्ल को पार्स करने का प्रयास करना है, यह बताएं कि कथन क्या करना चाहता है, और, यदि यह काफी आसान है, तो उचित ऑब्जेक्ट विधि को प्रतीकात्मक संदर्भ के माध्यम से कॉल करें। यह स्पष्ट रूप से पागल है।

क्या कुछ तार्किक समाधान है जो मैं देख रहा हूं?

+1

+1 "यह स्पष्ट रूप से पागल है।" –

उत्तर

9

एक दृष्टिकोण है कि mod_perl CGIs संकलित करने के लिए उपयोग करता है के लिए इसी तरह लेने की कोशिश करें:

  1. पर्ल कोड में कन्वर्ट टेम्पलेट। एक sub { ... } कि कोड के आसपास

    print "<p>Welcome, "; 
    print $user->query('name'); 
    print ".\n"; 
    
  2. लपेटें, कुछ कोड के साथ (, उदा नमूने में $user जैसी चीजों के लिए) तर्क खोल रहे हैं: उदाहरण के लिए, अपना पहला उदाहरण की तरह कुछ करने के लिए कनवर्ट कर सकते हैं।

  3. eval वह कोड। ध्यान दें कि यह एक coderef देता है।

  4. उस कोड को बार-बार कॉल करें। :)

+5

एक संबंधित दृष्टिकोण जेनरेट कोड को '.pm' फ़ाइल में लिखना होगा और उसके बाद उस मॉड्यूल को लोड करना होगा। इस तरह, टेम्पलेट को बदलने पर केवल मरम्मत की आवश्यकता होगी। कौन सा तरीका बेहतर है ऐप को कार्यान्वित करने के विवरण के आधार पर निर्भर करता है। – cjm

+0

वाह, यह शानदार है! यह मुझे एक गैज़िलियन टेम्पलेट्स को फिर से लिखने के बिना समस्या को ठीक करने देता है। मैं कोशिश करूँगा, धन्यवाद! – parsim

+0

यह वही है [टेम्पलेट टूलकिट] (http://template-toolkit.org) करता है। –

2

आप Text::MicroTemplate की हिम्मत को देखना चाहते हैं। वास्तव में, आप टेक्स्ट :: माइक्रोटेम्प्लेट का उपयोग करना चाहेंगे, क्योंकि यह आपकी आवश्यकताओं के अनुरूप हो सकता है। यह एक सबराउटिन बनाता है जो स्ट्रिंग को आवश्यकतानुसार संयोजित करता है, जैसा कि डस्कवफ सुझाव दिया जाता है। यहाँ re.pl में build_mt('hello, <?= $_[0] ?>') का परिणाम है:

$CODE1 = sub { 
     package Devel::REPL::Plugin::Packages::DefaultScratchpad; 
     use warnings; 
     use strict 'refs'; 
     local $SIG{'__WARN__'} = sub { 
     print STDERR $_mt->_error(shift(), 4, $_from); 
     } 
     ; 
     Text::MicroTemplate::encoded_string(sub { 
     my $_mt = ''; 
     local $_MTREF = \$_mt; 
     my $_from = ''; 
     $_mt .= 'hello, '; 
     $_from = $_[0]; 
     $_mt .= ref $_from eq 'Text::MicroTemplate::EncodedString' ? $$_from : do { 
      $_from =~ s/([&><"'])/$Text::MicroTemplate::_escape_table{$1};/eg; 
      $_from 
     }; 
     return $_mt; 
     } 
     ->(@_)); 
    }; 
+0

मदद के लिए धन्यवाद! मैं वर्तमान टेम्पलेटिंग सिस्टम को प्रतिस्थापित किए बिना इस से बचने की उम्मीद कर रहा हूं, क्योंकि यह काफी बड़ी नौकरी होगी। लेकिन अगर यह बहुत अधिक परेशानी हो जाती है, तो मैं माइक्रोटेम्प्लेट को देखूंगा। – parsim

3

आप Mojolicious पर एक नज़र हो सकता है। इसमें templating engine है जो आपके द्वारा उपयोग किए जा रहे सिंटैक्स की अनुमति देता है।आप संभवतः इसका उपयोग करने के लिए स्विच कर सकते हैं या इसके स्रोत को देख सकते हैं (पिछले लिंक के बाईं ओर स्रोत पर क्लिक करें) यह देखने के लिए कि क्या आप कुछ विचार खींच सकते हैं।

FYI करें Mojolcious templating इंजन की वाक्य रचना उचित रूप से

<% Perl code %> 
<%= Perl expression, replaced with result %> 
<%== Perl expression, replaced with XML escaped result %> 
<%# Comment, useful for debugging %> 
<%% Replaced with "<%", useful for generating templates %> 
% Perl code line, treated as "<% line =%>" 
%= Perl expression line, treated as "<%= line %>" 
%== Perl expression line, treated as "<%== line %>" 
%# Comment line, treated as "<%# line =%>" 
%% Replaced with "%", useful for generating templates 
+0

धन्यवाद! जैसा कि मैंने जोश को पोस्ट किया था, मैं उम्मीद कर रहा हूं कि पूरे टेम्पलेटिंग सिस्टम को प्रतिस्थापित करने से बचें, क्योंकि यह 10 साल पुराना सॉफ्टवेयर है और उनको संशोधित करना मुश्किल है। लेकिन मैंने Mojolicious के बारे में अच्छी बातें सुनी है। – parsim

+0

मैं पूरी तरह से समझता हूं! फिर भी शायद इसका कोड आपको कुछ विचारों के साथ मदद कर सकता है। –

+1

@ जोएल बेर्जर हर जगह यह प्रश्न "इडियट यूपी सीपीएएन" प्रतिक्रिया प्राप्त करेगा। मेरे दोस्त को भयानक होने के लिए +1। – Hawken

0

आप eval 'नहीं का उपयोग करना चाहिए अपने खाके में तरीकों कॉल करने के लिए HTML के साथ intermixed निम्न रूपों अनुमति देता है। ध्वनि कठोर करने के लिए खेद है लेकिन एक अलग दृश्य का बिंदु दृश्य परत से प्रसंस्करण कोड को निकालना है। टेम्पलेट टूलकिट के साथ ऊपर वर्णित टेम्पलेट सिस्टम बस एक ऑब्जेक्ट/हैश में पास करते हैं ताकि आप इसे एक्सेस कर सकें। यह आप के साथ 'नाम' का उपयोग करने की अनुमति देगा

$user = { 
     'name' => 'John', 
     'id' => '3454' 
     }; 

:

क्यों की तरह एक hashref के रूप में $ उपयोगकर्ता पारित नहीं

$user->{'name'}; 

अन्यथा, यह है कि आप है कि आप कर रहे हैं की संभावना है कुछ ऐसा करना:

  1. टेम्पलेट $ user-> क्वेरी() कॉल करता है;
  2. विधि मूल्य प्राप्त करने के डीबी कॉल
  3. विधि रिटर्न मूल्य

टेम्पलेट के लिए हैश/वस्तु संदर्भ पारित करने के लिए की तुलना में एक डेटाबेस क्वेरी बनाने के लिए अधिक महंगी soooo है यही कारण है कि। आप कोड निष्पादन का कौन सा हिस्सा वास्तव में धीमा कर रहे हैं यह देखने के लिए आप कुछ कोड प्रोफाइलिंग टूल जैसे डेवेल :: NYTProf को देखना चाहते हैं। मुझे संदेह है कि eval आपके प्रोग्राम को इतनी परेशान कर रहा है कि आपको eval को अनुकूलित करने की आवश्यकता है। Eval के अंदर कोड की तरह लगता है कि आप क्या धीमा कर रहा है।

+0

मैंने NYTProf चलाया, और ऐसा लगता है कि eval खुद मंदी का एक महत्वपूर्ण स्रोत है। यह कुल सर्वर समय का केवल 5-10% उपभोग कर रहा है, लेकिन यह भी सबसे बड़ा बिंदु है। $ User-> {$ value} के साथ $ user-> क्वेरी ($ मान) कॉल को प्रतिस्थापित करने के लिए वास्तव में व्यवहार्य नहीं है क्योंकि & query sub अक्सर वास्तव में मूल्य को देखने से परे कुछ करता है। इसके अलावा, यह कई लोगों के बीच सिर्फ एक कॉल है। – parsim

+0

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

+0

उत्तर यह है कि वेब ऐप में एमवीसी आर्किटेक्चर नहीं है। (क्या मैंने इसका उल्लेख लगभग 10 साल पुराना है?) टेम्पलेट प्रभावी ढंग से ऐप चलाते हैं। इसे बदलने के लिए यह एक बड़ा काम होगा, इसलिए मैं इसके साथ अटक गया हूं। – parsim

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