2010-09-13 19 views
18

मैं एक छोटे से डीएसएल पर काम कर रहा हूं जो ओवरलोडेड मानों पर प्रयुक्त ऑपरेटरों को कैप्चर करने के लिए ओवरलोडिंग के लिए nomethod फ़ॉलबैक का उपयोग करता है। यह के कार्य के समान है जो overload के दस्तावेज़ में वर्णित है।क्या पर्ल में रेगेक्स बाध्यकारी ऑपरेटर `= ~` अधिभारित करने का कोई तरीका है?

यह मानक तुलना ऑपरेटरों के लिए ठीक काम करता है, लेकिन निम्नलिखित पर विचार:

my $ret = $overloaded =~ /regex/; 

इस मामले में, nomethod$overloaded stringify को कहा जाता है, और उसके बाद से अधिक भार खो दिया है हो जाता है। मैंने एक बंधे हुए चर को वापस करने के बारे में सोचा, जो कम से कम मुझे मूल अधिभारित वस्तु के आसपास ले जाने देगा, लेकिन यह अभी भी रेगेक्स के निष्पादन के दौरान खो जाएगा।

तो, परम सवाल अगर वहाँ एक प्रतीकात्मक कैलकुलेटर की 'overload रों विचार का विस्तार करने के लिए regex बाध्यकारी ऑपरेटरों =~ और !~ शामिल करने के लिए किसी भी तरह से है, तो यह है कि इसके बाद के संस्करण कोड नमूना ($overloaded, qr/regex/, 0, '=~') या कुछ इसी तरह के साथ nomethod कहेंगे है?

मैंने स्मार्टमैच ऑपरेटर ~~ को ओवरलोड करने में भी संक्षेप में देखा लेकिन ऐसा लगता है कि यह चाल भी नहीं है (हमेशा अधिभार के बजाय रेगेक्स मिलान के लिए डिफ़ॉल्ट)।

संपादित करें: मैंने ~~ और अधिक देखा, और पाया कि my $ret = $overloaded ~~ q/regex/ स्मार्टमैचिंग नियमों के कारण काम करता है। बंद करें, लेकिन आदर्श समाधान नहीं है, और मैं इसे पूर्व 5.10 काम करना चाहता हूं, इसलिए मैं अन्य उत्तरों का स्वागत करता हूं।

+0

मुझे लगता है कि रेगेक्स इंजन में एक रैपर की आपूर्ति करना या तो काम नहीं करेगा यदि आप इसे 5.10 से पहले काम करना चाहते हैं। –

+0

पागलपन खत्म करो! पायथन सीखो! – bukzor

+0

@bukzor: मुझे पूरा यकीन है कि आप पायथन में रेगेक्स बाध्यकारी ऑपरेटर को अधिभारित नहीं कर सकते हैं, क्योंकि इसमें कोई नहीं है। बेशक, आप एक कक्षा लिख ​​सकते हैं जो आपको समान, सीमित कार्यक्षमता प्रदान करेगी: http://code.activestate.com/recipes/302498-re-match-and-replace-through-operator-overloading/ –

उत्तर

2

मुझे लगता है कि डीएसएल source filters के साथ पर्ल में सबसे अच्छी तरह लिखे गए हैं। आप सचमुच कुछ भी कर सकते हैं जो आप चाहते हैं। ;-) आपके उदाहरण में, आप myfunc (FOO, BAR) के साथ FOO = ~ BAR को प्रतिस्थापित कर सकते हैं और मनमानी कोड चला सकते हैं।

यहाँ एक उदाहरण समाधान है:

# THE "MyLang" SOURCE FILTER 
package MyLang; 
use strict; 
use warnings; 
use Filter::Util::Call; 

sub import { 
    my ($type, @args) = @_; 
    my %p = @args; 
    no strict 'refs'; 
    my $caller = caller; 
    # Create the function to call 
    *{"${caller}::_mylang_defaultmethod"} = sub { 
     my ($a, $op, $b) = @_; 
     $p{nomethod}->($a, $b, 0, $op); 
    }; 
    my ($ref) = []; 
    filter_add(bless $ref); 
} 

sub filter { 
    my ($self) = @_; 
    my ($status); 
    if ($status = filter_read() > 0) { 
     $_ =~ s/([^=]+)(=~)([^;]+)/ _mylang_defaultmethod($1,'$2',$3)/g; 
    } 
    $status; 
} 

1; 

उदाहरण का उपयोग

use MyLang nomethod => \&mywrap; 

my $a = "foo"; 
my $b = "bar"; 
$x = $a =~ $b; 

sub mywrap { 
    my ($a, $b, $inv, $op) = @_; 
    print "$a\n"; 
} 

के बाद से यह क्या है चर "एक $" में है अब ऊपर प्रिंट होगा "foo \ n"। बेशक आप फिल्टर में रेगेक्स प्रतिस्थापन के लिए कुछ और अधिक बुद्धिमान पार्सिंग करना चाह सकते हैं, लेकिन यह अवधारणा का एक सरल सबूत है।

+0

डाउनवोट क्यों? –

+0

क्योंकि आप पिंग पोंग – mkoryak

+0

पर चूसते हैं क्योंकि शायद सामान्य रूप से, स्रोत फ़िल्टर एक नाजुक समाधान होते हैं, खासकर जब फ़िल्टर में संदर्भ-संवेदनशील सीमाएं होती हैं। आपका उदाहरण '$ x = $ a = ~ $ b' के मामले में काम करता है, लेकिन' $ x = myfunc $ a = ~ $ b' के साथ विफल हो जाएगा। इस तरह के स्रोत फ़िल्टर के लिए वास्तव में बहुत मजबूत होने के लिए बहुत सारे कोने के मामले हैं। इसके अतिरिक्त, यदि आप एक स्रोत फ़िल्टर लिखने का प्रयास करते हैं, तो आपको कम से कम 'code ::no' को 'code_no_comments' संशोधक' के साथ उपयोग करना चाहिए ताकि आप केवल कोडेलिक क्षेत्रों को फ़िल्टर कर रहे हों, न कि टिप्पणियां, पॉड या उद्धृत तारों को। –

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

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