我该如何在Perl 6中重新定义对象? [英] How can I rebless an object in Perl 6?
问题描述
另一个问题可能是如何从内置类型继承?".
Another question might be "How do I inherit from builtin types?".
我确实有两个问题,但这两个问题都是我玩的同一件事.
I have two questions really, but they are both from the same thing I'm playing with.
首先,当我想进一步限制类型时,可以制作该类型的子集.我用MyInt
来做,它接受任何Int
.我通过MyInt
声明一个变量并将其分配给它,但是当我检查它的名称时,我得到的是Int
.那么,那是怎么回事?
First, I can make a subset of a type when I want to constrain it further. I do that with MyInt
which accepts anything that is an Int
. I declare a variable to by MyInt
and assign to it, but when I check its name, I get Int
instead. So, what's up with that?
subset MyInt where * ~~ Int;
my MyInt $b = 137;
put 'Name: ', $b.^name; # Int, but why not MyInt?
但是,我真正想要的是一个名为MyInt
的类,它可以完成相同的操作.我可能想将方法添加到
But, what I really wanted was a class named MyInt
that does the same thing. I might want to add methods to
class MyInt is Int {} # empty subclass
my MyInt $b = 137;
put 'Name: ', $b.^name;
这看起来好像可行,但出现错误:
This almost looks like it works, but I get an error:
Type check failed in assignment to $b; expected MyInt but got Int (137)
我理解这是什么意思,但是不明白为什么我在使用subset
时没有得到同样的错误.问题1.5.
I understand what it's saying, but don't understand why I didn't get the same error when I used subset
. That's question 1.5.
我真正想要的是分配137,以便在分配它时自动将其自身转换为MyInt
.我知道我可以显式构造它,但是令人讨厌的是,父类仍将其转换为Int
,而不是使用更多派生类型的类型:
What I'd really like is the assignment of 137 to automatically turn itself into a MyInt
when I assign it. I know that I can explicitly construct it, but it's a bit annoying that the parent class still turns it into an Int
instead of using the type of the more derived type:
class MyInt is Int {} # empty subclass
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
我可以覆盖new
(直接取自 Int .pm ),但我对更改类型一无所知:
I can override the new
(taken directly from Int.pm), but I'm at a loss about change the type:
class MyInt is Int {
method new ( $value --> MyInt ) {
my $v = callsame; # let superclass construct it
# But, how do I make it the more specific type?
}
}
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
我可以bless
自我,但是那并不能保留价值(而且我不认为这样,也不认为应该这样.看着
I can bless
self, but that doesn't retain the value (and I didn't think it would and don't think it should. Looking at Int.pm, I can't see how it stores the value. It looks like it relies on a built-in type and might not be traditionally subclassable:
class MyInt is Int {
method new ( $value --> MyInt ) {
my $v = callsame; # let superclass construct it
put "v is $v";
# But, how do I make it the more specific type?
# $v.bless (doesn't change the type, fails return type check)
self.bless; # doesn't retain value
}
}
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
put 'Value: ', $b; # 0
有一个 rebless ,但这不属于可用于Int
或ClassHow
:
There is a rebless, but that isn't part of the chain of things avialable to Int
or ClassHow
:
class MyInt is Int {
method new ( $value --> MyInt ) {
my $v = callsame; # let superclass construct it
put "v is $v";
put "self is " ~ self.^name;
put "HOW is " ~ self.HOW.^name;
# No such method 'rebless' for invocant
# $v.rebless: self.^name;
$v.HOW.rebless: self.^name;
}
}
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
put 'Value: ', $b; # 0
推荐答案
以下是可能的解决方案:
Here's a possible solution:
class MyInt is Int { };
my $x = 42;
Metamodel::Primitives.rebless: $x, MyInt;
dd $x;
哪个会产生:
MyInt $x = 42
可能有一种更清洁的方式来做您想要的事情,但我不知道它是什么.
There's probably a cleaner way of doing what you want, but I don't know what it is.
重要更新请参见 Raku rebless不会不再使用继承的类.
这篇关于我该如何在Perl 6中重新定义对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!