Perl 6:使用AT-POS进行可写的多维下标访问

msc*_*cha 4 perl6

您可以使用以下命令轻松允许下标访问您自己的类AT-POS:

class Foo
{
    has @.grid;

    method AT-POS($x) is rw { return-rw @!grid[$x] }
    method Str { '<' ~ @!grid.join(' ') ~ '>' }
    method gist { self.Str }
}

my $foo = Foo.new(:grid(<a b c d e>));
say $foo;
say $foo[2];
$foo[3] = 'z';
say $foo;
Run Code Online (Sandbox Code Playgroud)

输出:

<a b c d e>
c
<a b c z e>
Run Code Online (Sandbox Code Playgroud)

但我需要二维下标访问.我已经想出如何让这个工作用于阅读,但它在写作时死亡:

class Bar
{
    has @.grid;

    method AT-POS($y, $x) is rw { return-rw @!grid[$y;$x] }
    method Str { '<' ~ @!grid».join(' ').join("\n ") ~ '>' }
    method gist { self.Str }
}

my $bar = Bar.new(:grid(<a b c d e>, <f g h i j>, <k l m n o>));
say $bar;
say $bar[1;2];
$bar[2;3] = 'z';
say $bar;
Run Code Online (Sandbox Code Playgroud)

输出:

<a b c d e
 f g h i j
 k l m n o>
h
Too few positionals passed; expected 3 arguments but got 2
  in method AT-POS at ./p6subscript line 25
  in block <unit> at ./p6subscript line 33
Run Code Online (Sandbox Code Playgroud)

有没有办法让这项工作?

jjm*_*elo 5

不知何故,该AT-POS方法没有被调用.该文件提到使用的ASSIGN-POS替代,所以在这里我们去:

class Bar
{
    has @.grid is rw;

    method AT-POS($y, $x) is rw { say "AT-POS $y, $x"; return-rw @!grid[$y;$x] }
    method ASSIGN-POS($y, $x, $new) { say "ASSIGN-POS $y, $x"; @!grid[$y;$x] = $new }
    method Str { '<' ~ @!grid».join(' ').join("\n ") ~ '>' }
    method gist { self.Str }
}

my $bar = Bar.new(:grid(<a b c d e>, <f g h i j>, <k l m n o>));
say $bar;
say $bar[1;2];
$bar[2;3] = 'z';
say $bar;
Run Code Online (Sandbox Code Playgroud)

有趣的是,这产生了另一个错误:

Array

所以问题不在于语法,而是在使用不可变列表这一事实.你应该使用AT-POSs,这是可变的,你将能够做到这一点.

Cannot modify an immutable List ((k l m n o))
  in method ASSIGN-POS at semilist-so.p6 line 8
  in block <unit> at semilist-so.p6 line 16
Run Code Online (Sandbox Code Playgroud)


Eli*_*sen 3

我的解决方案是(假设我们只有两个维度):

\n\n
class Bar {\n    has @.grid;\n\n    method TWEAK() { $_ .= Array for @!grid }\n    method AT-POS(|c) is raw { @!grid.AT-POS(|c) }\n    method Str { \'<\' ~ @!grid\xc2\xbb.join(\' \').join("\\n ") ~ \'>\' }\n    method gist { self.Str }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

TWEAK如果尚未将列表转换为数组,则会将其转换。on就是所需要的:这是is raw一种非常迂回的方法。AT-POSreturn-rw

\n