एक कस्टम घोषणाकर्ता


9

मान लें कि मैं बॉयलरप्लेट के एक निश्चित सेट का नियमित रूप से उपयोग करता हूं:

class Foo {

  method abc($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

  method xyz($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

  method blarg($a: $b, $c, +@d) is pure {
    use Slang::Bar;
    …
  }

}

मैं सिर्फ कहने में सक्षम हो जाएगा:

class Foo is/does Bar {
  bar  abc   { … }
  bar  xyz   { … }
  bar  blarg { … }
}

और कहीं बार में, बार के लिए घोषणा सेट करें (या, क्योंकि क्लास फू स्वयं अंततः अपने स्वयं के घोषणाकर्ता का उपयोग करेगा, यह कहीं और जा सकता है और एक अलग प्रकार में बाहर निकालना नहीं है)। मुझसे यह कैसे होगा?


मुझे लगता है कि यह मूल रूप से पूछ रहा है "मैं कैसे करूँ?" लेकिन मैंने कोई वास्तविक लेखन अप नहीं देखा है, और इसका उपयोग करने वाले एक्स्टेंट मॉड्यूल (रेड / क्रो) काफी जटिल हैं (यदि सुंदर) जानवर जो एक नज़र में पालन करना मुश्किल है।
user0721090601

ऐसा लगता है कि आप हस्ताक्षर का पुन: उपयोग करना चाहते हैं, है ना?
jjmerelo

2
jjmerelo: नहीं, वास्तव में अंतिम लक्ष्य एक विधि उपवर्ग करना है (वर्ग के साथ इसे दर्ज करना अगर इसके अंदर उपयोग किया जाता है) और कोड ब्लॉक के अंदर एक पूरी तरह से अलग भाषा का उपयोग करना (इस मामले में एक
रेगीक्स

2
jjmerelo: gist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04d प्रस्ताव के लिए देखें । मैं दिखाने के लिए एक परीक्षण मॉड्यूल रखने से कुछ दिन दूर हूं, लेकिन मुझे
बिनेक्स के

जवाबों:


5

-1। सीमाएँ (केवल संकुल के लिए)

विधि एक्सपोर्टर कॉल को .set_how करंट पर $?LANGएक स्लैंग को बाद में जोड़ता है।
फिर यह add_package_declarator है MAIN $?LANGजो package_declaratorइसके कार्य और व्याकरण में एक विधि जोड़ता है । यह है, मुझे लगता है, केवल "गतिशील कठबोली" (World.nqp में)।

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

ध्यान दें: एक पैकेज एक कंटेनर (पैकेज, व्याकरण, मॉड्यूल, भूमिका, पता, Enum, वर्ग, सबसेट) है। यदि आप एक विधि की तरह अंदर कोड डालते हैं, तो यह निष्पादित हो जाता है (मैं सिर्फ कोशिश करूँगा):

0. विवरण (एक्सपोर्ट)

मैं undocumented EXPORTHOW और DECLAREएक मॉड्यूल में उपयोग करूंगा क्योंकि मुझे Phaser के साथ कोई रास्ता नहीं मिला । जाहिरा तौर पर यह BEGIN में बहुत देर हो चुकी है।

मैं जो उदाहरण देता हूं, वह प्रत्येक विधि को एक कक्षा में (यहां तक ​​कि BUILDALL) सजा रहा है ।

1. लिब ( decorator.rakumod)

class DecoratedClassHOW is Metamodel::ClassHOW {
    method add_method(Mu $obj, $name, $code_obj) {
        sub wrapper ($obj, $a, $b) {
            say "Before $name";
            my $res = $code_obj($obj, $a, $b);
            say "After $name";
            return $res;
        }
        my $res = callwith($obj, $name, &wrapper);
        return $res;
    }
}

my module EXPORTHOW {
    package DECLARE {
        constant decorated = DecoratedClassHOW;
    }
}

2. निष्पादन योग्य

use lib '.';
use decorator-lib;

decorated Foo {
  method abc($a, $b) {
      say "In abc: $a:$b";
  }
}

my $f = Foo.new;
$f.abc(1, 2);

3. आउटपुट

Before BUILDALL
After BUILDALL
Before abc
In abc: 1:2
After abc

4. सूत्र


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