การประกาศที่กำหนดเอง


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 { … }
}

และที่ใดที่หนึ่งใน Bar ตั้งค่าการประกาศสำหรับ bar (หรือเนื่องจาก class Foo จะใช้ตัวประกาศของตัวเองในท้ายที่สุดมันสามารถไปที่อื่นและไม่ต้องดึงออกมาแยกประเภท) ฉันจะทำยังไงต่อไป?


ฉันเข้าใจว่านี่เป็นคำถามที่ถามว่า "ฉันจะทำอย่างไรดี?" แต่ฉันไม่เคยเห็นการเขียนที่แท้จริงใด ๆ และโมดูลที่มีอยู่ที่ใช้ (แดง / Cro) นั้นค่อนข้างซับซ้อน (ถ้าสวยงาม) สัตว์ที่ยากที่จะติดตามได้อย่างรวดเร็ว
user0721090601

ดูเหมือนว่าคุณต้องการใช้ลายเซ็นซ้ำใช่ไหม
jjmerelo

2
jjmerelo: ไม่จริงเป้าหมายสูงสุดคือการทำวิธีการ subclass (การลงทะเบียนกับคลาสถ้าใช้ภายใน) และใช้ภาษาที่แตกต่างกันโดยสิ้นเชิงในโค้ดบล็อก (ในกรณีนี้คือ regex)
user0721090601

2
jjmerelo: ดูgist.github.com/alabamenhu/2fec7a8f51a24091dc1b104a2ae2f04dสำหรับข้อเสนอ ฉันอยู่ห่างจากการทดสอบโมดูลไม่กี่วัน แต่ฉันมีโลจิสติกส์ส่วนใหญ่ของ Binex ที่ทำงาน แต่สำหรับไวยากรณ์ที่คล้าย Raku
user0721090601

คำตอบ:


5

-1 ข้อ จำกัด (เฉพาะสำหรับแพ็คเกจ)

วิธีการส่งออกEXPORTHOW .set_howในปัจจุบัน$?LANGเพิ่มคำสแลงไปที่หลัง
จากนั้นก็จะadd_package_declaratorไปMAIN $?LANGซึ่งจะเพิ่มpackage_declaratorวิธีการในการดำเนินการและไวยากรณ์ของมัน ฉันคิดว่ามันเป็น "ไดนามิกสแลง" เพียงอย่างเดียว (ใน World.nqp)

หากสิ่งที่คุณต้องการคือการเขียนทับroutine_declarator จากนั้นคุณต้องเขียนคำสแลงเลียนแบบห่วงโซ่ที่อ้างถึง หากคุณยอมรับที่จะเก็บคีย์เวิร์ดของเมธอดและสร้างลายเซ็นอัตโนมัติในคลาสให้พูดตามชื่อเมธอดนี่คือวิธี:

หมายเหตุ: แพ็กเกจคือคอนเทนเนอร์ (แพ็กเกจ, ไวยากรณ์, โมดูล, บทบาท, Knowhow, enum, คลาส, เซ็ตย่อย) หากคุณใส่โค้ดในรูปแบบวิธีการนี้จะถูกดำเนินการ (ฉันเพิ่งลอง):

0. คำอธิบาย (EXPORTHOW)

ผมจะใช้ที่ไม่มีเอกสารEXPORTHOWและDECLAREในโมดูลเพราะผมไม่ได้หาวิธีที่มีPhaser เห็นได้ชัดว่ามันสายเกินไปที่ BEGIN

ตัวอย่างที่ฉันให้คือการตกแต่งทุกวิธีในชั้นเรียน (คู่BUILDALL)

1. Lib ( 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.