我如何在Perl 6中重新分配一个对象?

另一个问题可能是“我如何继承内置类型?”。

我真的有两个问题,但他们都来自我玩的同一件事。

首先,当我想进一步限制它时,我可以创建一个类型的子集。 我用MyInt来接受任何是Int东西。 我通过MyInt声明一个变量并赋值给它,但是当我检查它的名字时,我得到了Int 。 那么,这是怎么回事?

subset MyInt where * ~~ Int;

my MyInt $b = 137;
put 'Name: ', $b.^name;  # Int, but why not MyInt?

但是,我真正想要的是一个名为MyInt的类,它可以做同样的事情。 我可能想要添加方法

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 。 我知道我可以明确地构造它,但有点烦人的是,父类仍将它变成一个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,我看不出它是如何存储价值的。它依赖于内置类型,可能不是传统上可分类的:

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,但这不属于IntClassHow

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

可能有更干净的方式来做你想做的事,但我不知道它是什么。

链接地址: http://www.djcxy.com/p/39709.html

上一篇: How can I rebless an object in Perl 6?

下一篇: Spring @Transactional commit failures ; Deby + Eclipselink