使用POSITIONS和Code对象时出现问题

时间:2019-04-30 08:36:35

标签: perl6

我正在尝试创建实现POSTIONS进行切片的对象

class Foo is Code { 
    multi method POSITIONS( Foo:D $foo: \pos) { 1,2 }
}; 
say <a b c>[Foo.new]

“无法使用.new创建Foo对象”的错误。

将其制成独立对象不会调用POSITIONS:

class Foo { method POSITIONS { 1 } };
my Foo $foo .= new; 
say <a b c>[$foo] # No such method 'Int' for invocant of type 'Foo'␤ 

这里的主要问题是:调用POSITIONS创建切片的条件是什么?

但是,第二个问题是:为什么Code对象无法实例化?

1 个答案:

答案 0 :(得分:5)

我不认为Code使用new进行对象构造。这是一个非常基础的课程。对于source code,实际需要的是Callable,这是应用任何类的简单角色。我个人希望它能呼叫CALL-ME

对于您的第二个示例,我们可以找到

multi sub postcircumfix:<[ ]>( \SELF, Any:D \pos ) is raw {
    SELF.AT-POS(pos.Int);
}

因此,如果事先不考虑类型,它将尝试强制转换为您的班级没有的Int

您的第一个应该通过将其更改为

即可工作
class Foo does Callable { 
  method POSITIONS(\foo) { 1 }
};
my Foo $foo .= new; 
say <a b c>[$foo]

但是此错误,抱怨Foo没有实现.pos。我可以看到,但没有在源代码中记录该功能,但是实现该功能确实可以使事情神奇地起作用:

class Foo does Callable { 
  method POSITIONS(|c)   { (0,1,2,(0,1),(0,2),(1,2),(0,1,2),(0..2)).pick }
  method pos(|c)         { self.POSITIONS: c }
};
my Foo $foo .= new; 
say <a b c>[$foo]

传递给pos的位置参数是要切片的列表(在您的示例中为(a b c)),如果要根据数组内容调整切片,grep / map风格。

编辑:

实际上,愚弄我。 pos was renamed to POSITIONS和TIO(我正在测试的)未更新。由于发生了这种变化,我建议同时使用posPOSITIONS,对于使用旧版实现的任何人,只需在POSITIONS内部调用pos