Đối với một thư viện tôi đang viết, tôi có một thuộc tính trên CÁCH sử dụng handles
đặc điểm để ủy thác các phương thức của các vai trò khác nhau được thực hiện bởi một CÁCH khác mà nó sử dụng cho một thể hiện của CÁCH đó. Nỗ lực đầu tiên của tôi trông như thế này (mặc dù để làm cho nó dễ đọc hơn, điều này sẽ chỉ giải quyết Metamodel::Naming
):
class ParentHOW does Metamodel::Naming {
method new_type(ParentHOW:_: Str:D :$name!, Str:D :$repr = 'P6opaque' --> Mu) {
my ::?CLASS:D $meta := self.new;
my Mu $type := Metamodel::Primitives.create_type: $meta, $repr;
$meta.set_name: $type, $name;
$type
}
}
class ChildHOW {
has Mu $!parent;
has Mu $!parent_meta handles <set_name shortname set_shortname>;
submethod BUILD(ChildHOW:D: Mu :$parent is raw) {
$!parent := $parent;
$!parent_meta := $parent.HOW;
}
method new_type(ChildHOW:_: Mu :$parent is raw) {
my ::?CLASS:D $meta := self.new: :$parent;
Metamodel::Primitives.create_type: $meta, $parent.REPR
}
method name(ChildHOW:D: Mu \C --> Str:_) { ... }
}
my Mu constant Parent = ParentHOW.new_type: :name<Parent>;
my Mu constant Child = ChildHOW.new_type: :parent(Parent);
say Child.^shortname; # OUTPUT: Parent
Vấn đề với điều này là nếu bất kỳ loại nào tôi thực hiện CÁCH này xử lý các phương thức cho từng thay đổi, thì điều này sẽ không còn hoạt động với tất cả các phương thức của chúng. Vì vậy, thay vào đó tôi muốn tự động tạo ra một danh sách các phương thức nên được xử lý đưa ra một danh sách các phương thức mà CÁCH này ghi đè và một danh sách các loại có phương thức nên được xử lý. Điều này không dễ dàng như âm thanh vì cách handles
tính trạng được thực hiện. Ví dụ, điều này sẽ không hoạt động:
has Mu $!parent_meta handles do {
my Array[Str:D] constant PARENT_METHOD_OVERRIDES .= new: <name>;
((), Metamodel::Naming)
.reduce({ (|$^methods, |$^role.HOW.methods: $^role) })
.map(*.name)
.grep(PARENT_METHOD_OVERRIDES ∌ *)
};
Vì vậy, làm thế nào bạn có thể tự động tạo ra một giá trị cho một đặc điểm để sử dụng trong các trường hợp như thế này?