我怎样才能在 Perl 6 中重新祝福一个对象?
How can I rebless an object in Perl 6?
另一个问题可能是 "How do I inherit from builtin types?"。
我真的有两个问题,但它们都来自我正在玩的同一件事。
首先,当我想进一步限制它时,我可以创建一个类型的子集。我用 MyInt
来做到这一点,它接受任何 Int
。我通过 MyInt
声明了一个变量并分配给它,但是当我检查它的名称时,我得到的是 Int
。那么,这是怎么回事?
subset MyInt where * ~~ Int;
my MyInt $b = 137;
put 'Name: ', $b.^name; # Int, but why not MyInt?
但是,我真正想要的是一个名为 MyInt
的 class 来做同样的事情。我可能想将方法添加到
class MyInt is Int {} # empty subclass
my MyInt $b = 137;
put 'Name: ', $b.^name;
这几乎看起来可行,但我收到一个错误:
Type check failed in assignment to $b; expected MyInt but got Int (137)
我明白它在说什么,但不明白为什么我在使用 subset
时没有得到同样的错误。这是问题 1.5.
我真正想要的是 137 的赋值在我赋值时自动将其自身变成 MyInt
。我知道我可以显式构造它,但是有点烦人的是父 class 仍然将它变成 Int
而不是使用更派生类型的类型:
class MyInt is Int {} # empty subclass
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
我可以覆盖 new
(直接取自 Int.pm),但我不知道如何更改类型:
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
自己,但这并没有保留价值(我不认为它会也不应该。看着 Int.pm,我可以'看不到它是如何存储值的。看起来它依赖于内置类型,并且传统上可能不是 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
可用的链的一部分:
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
这是一个可能的解决方案:
class MyInt is Int { };
my $x = 42;
Metamodel::Primitives.rebless: $x, MyInt;
dd $x;
产生:
MyInt $x = 42
可能有一种更简洁的方法来执行您想要的操作,但我不知道它是什么。
重要更新请参阅。
另一个问题可能是 "How do I inherit from builtin types?"。
我真的有两个问题,但它们都来自我正在玩的同一件事。
首先,当我想进一步限制它时,我可以创建一个类型的子集。我用 MyInt
来做到这一点,它接受任何 Int
。我通过 MyInt
声明了一个变量并分配给它,但是当我检查它的名称时,我得到的是 Int
。那么,这是怎么回事?
subset MyInt where * ~~ Int;
my MyInt $b = 137;
put 'Name: ', $b.^name; # Int, but why not MyInt?
但是,我真正想要的是一个名为 MyInt
的 class 来做同样的事情。我可能想将方法添加到
class MyInt is Int {} # empty subclass
my MyInt $b = 137;
put 'Name: ', $b.^name;
这几乎看起来可行,但我收到一个错误:
Type check failed in assignment to $b; expected MyInt but got Int (137)
我明白它在说什么,但不明白为什么我在使用 subset
时没有得到同样的错误。这是问题 1.5.
我真正想要的是 137 的赋值在我赋值时自动将其自身变成 MyInt
。我知道我可以显式构造它,但是有点烦人的是父 class 仍然将它变成 Int
而不是使用更派生类型的类型:
class MyInt is Int {} # empty subclass
my MyInt $b = MyInt.new: 137; # Still an Int
put 'Name: ', $b.^name;
我可以覆盖 new
(直接取自 Int.pm),但我不知道如何更改类型:
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
自己,但这并没有保留价值(我不认为它会也不应该。看着 Int.pm,我可以'看不到它是如何存储值的。看起来它依赖于内置类型,并且传统上可能不是 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
可用的链的一部分:
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
这是一个可能的解决方案:
class MyInt is Int { };
my $x = 42;
Metamodel::Primitives.rebless: $x, MyInt;
dd $x;
产生:
MyInt $x = 42
可能有一种更简洁的方法来执行您想要的操作,但我不知道它是什么。
重要更新请参阅