วิธีการนำไปใช้ใน Raku


13

ใน Perl โดยใช้Mooคุณสามารถใช้งานaroundsubs ซึ่งจะล้อมรอบวิธีอื่น ๆ ในชั้นเรียน

around INSERT => sub {
    my $orig = shift;
    my $self = shift;

    print "Before the original sub\n";
    my $rv  = $orig->($self, @_);
    print "After the original sub\n";
};

พฤติกรรมนี้สามารถนำไปใช้ในRakuโดยเฉพาะอย่างยิ่งการใช้role?

คำตอบ:


8

คุณสามารถเงาวิธีด้วยบทบาทจากนั้นใช้callwith:

class Foo {
    method meth { say 2 }
}

my $foo = Foo.new but role :: {
    method meth(|c) { say 1; callwith(|c); say 3 }
};

$foo.meth

8

วิธีการปรับเปลี่ยน ::

ใช้ฟังก์ชัน before (), after () และ around () ที่สามารถใช้ในการปรับเปลี่ยนวิธีการเรียนคล้ายกับ Moose ของ Perl 5 มันใช้ wrap () ภายในและส่งคืนตัวจัดการ wrapper ดังนั้นจึงง่ายต่อการเรียกคืน () ต้นฉบับ

นี่คือวิธีที่โมดูลดำเนินการaround:

sub around ($class, $method-name, &closure) is export
{
  $class.^find_method($method-name).wrap(method { closure(); });
}

6

ใช้ wrap

sub bar () { return "baþ" };

my $wrapped = &bar.wrap( { " → " ~ callsame() ~ " ← " } );

say bar(); # OUTPUT:  «→ baþ ← »

เนื่องจากวิธีการดังกล่าวเป็นกิจวัตรคุณจะต้องมีวิธีที่ซับซ้อนกว่านี้เล็กน้อยในการจัดการกับวิธีการเอง แต่นอกเหนือจากนั้นวิธีการนี้ก็เหมือนกันทุกประการเนื่องจากMethodsเป็นคลาสย่อยของRoutines

class Baz {
    method bar () { return "baþ" };
}

my &method_bar = Baz.^find_method("bar");
my $wrapped = &method_bar.wrap( { " → " ~ callsame() ~ " ← " } );

say Baz.bar(); # OUTPUT:  «→ baþ ← »

$wrappedเป็นหมายเลขอ้างอิงที่สามารถนำมาใช้ในภายหลังเพื่อแกะมันถ้าจำเป็น

แก้ไข : เพื่อเพิ่มรหัสเพื่อรับการจัดการกับวิธีการเรียนที่นำมาจากที่นี่เป็นต้น


การห่อไม่ได้ห่อวิธี
ugexe

@ugexe the OP อ้างอิงอย่างชัดเจนถึงหมวดย่อย นอกจากนี้คุณสามารถใช้วิธีการต่าง ๆ ได้เนื่องจากMethodเป็น aRoutine
jjmerelo

ฉันคิดว่าคุณสับสน คำถามตัวเองระบุ 'ห่อรอบวิธีอื่น ๆ ในชั้นเรียน' Mooรอบไม่มีอะไรที่เหมือนกับการห่อรูทีนย่อย
ugexe

@ugexe แตกต่างกัน วิธีการเป็นกิจวัตรตามที่ฉันพูดหลังจากการแก้ไข
jjmerelo
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.