从“执行”位置的类中的 AT-POS 方法(而不是代理实例)返回“原始”标量容器?

chr*_*mis 8 raku

我正在尝试实现一个“做”的类,Positional它也允许我通过分配给AT-POS方法返回的结果来更新它的值。最终,我能够编造以下按预期工作的类:

class Test does Positional
{
    has $.slot_1 is rw = 12;
    has $.slot_2 is rw = 24;

    method AT-POS(\position)
    {
        my $t = self;

        return-rw Proxy.new:

            FETCH => method ()
            {
                position % 2 ?? $t.slot_1 !! $t.slot_2
            },

            STORE => method ($v)
            {
                if position % 2
                {
                    $t.slot_1 = $v
                }
                else
                {
                    $t.slot_2 = $v
                }
            }
    }
}

my $test = Test.new;

die unless $test[2] == 24;

die unless $test[5] == 12;


$test[7] = 120;

die unless $test[2] == 24;

die unless $test[5] == 120;


$test[10] = 240;

die unless $test[2] == 240;

die unless $test[5] == 120;
Run Code Online (Sandbox Code Playgroud)

是否有可能以某种方式(和:简单地)返回容器绑定到$!slot_1(或$!slot_2)在Test类实现中?

在我发现使用Proxy实例之前,我试图return(和return-rw)表达式的结果position % 2 ?? $!slot_1.VAR !! $!slot_2.VAR,因为我的印象是该VAR方法让我可以访问底层容器,希望我可以简单地使用return它。这并没有真正起作用,我还不明白为什么:我怀疑它以某种方式被强制恢复为某个值?

换句话说:AT-POS在这种特殊情况下是否可以简化我的实现?

谢谢,

问候,

雷蒙德。

Eli*_*sen 7

假设您想要“slot_1”和“slot_2”的访问器,如果我正确理解了这个问题,这将是我的实现。我不会称它为Test类,因为这会干扰Test用于测试的类。

class Foo {
    has @elements = 24, 12;

    method AT-POS(Int:D $pos) is raw {
        @elements[$pos % 2]
    }
}

my $f = Foo.new;
say $f[2];  # 24
say $f[5];  # 12

$f[2] = 666;
say $f[4];  # 666
Run Code Online (Sandbox Code Playgroud)

请注意,数组中的默认值已更改顺序,这是为了使算术保持AT-POS简单。

还要注意方法is raw定义中的AT-POS:它将确保在返回值时不会发生去容器化。这允许您只分配给任何$f[2]回报。

希望这是有道理的!

另外:Array::Agnostic模块可能对您感兴趣,可以直接使用,或用作灵感来源。

  • 是的,这很有意义:“原始”特征正是我所寻找的东西。当我试图在其他地方实现此类功能时,我的这个命名不太恰当的类确实是从头开始设计和想象出来的。`Array::Agnostic` 实现确实很有趣并且值得进一步研究。谢谢! (3认同)