在Perl 6中使用其类中的公共和私有方法

Eug*_*sky 11 perl6

如果我有一个公共的方法,我可以同时使用调用它的类中$.nameself.name:

class TEST {
  has Int $.a;

  method b($x) {
    return $!a * $x;
  }

  method c($y) {
    return self.b($y) * 3; # or $.b($y)
  }
}

my $m = TEST.new(a => 10);
say $m.c(2); # 60
Run Code Online (Sandbox Code Playgroud)

但是,如果我创建b一个私有方法,我只能调用它self!b,而不是$!b,否则我收到以下错误消息:

Attribute $!b not declared in class TEST
Run Code Online (Sandbox Code Playgroud)

这条规则背后的原因是什么?在自己的类中调用方法的规则是什么?

Eli*_*sen 10

属性总是可以$!foo在类中引用.如果这样做,那么将生成代码以直接访问属性本身,并且任何子类化类的类将无法更改此行为.

如果您has $.foo在类的声明中使用,则意味着公共访问器(如果您添加is rw它也可以用作增变器).

当您使用$.foo在你的代码,否则,它是完全相同一样$( self.foo ).这意味着,它会调用该方法fooself,逐项和返回值(使它成为一个单一的"东西",如果它是目前还没有).如果你定义了你的属性$!foo并且你没有method foo自己提供,那么这将出错.

这甚至更进一步:$.bar真的意味着self.bar:你只需要一个名称存在的方法bar,这可能与任何属性都没有关系.

如果您定义一个私有方法!baz,!则只表示方法的隐私,这意味着您需要将其称为self!baz.它没有简短的语法.

就个人而言,我不喜欢$.zippo即使zippo不是属性你也可以说.但是我担心这艘船已经航行了.但这种行为现在引起你的困惑:-(

那么,为了调用私有方法没有短语法,规则背后的原因是什么?不确定,我想这$!foo实际上已经意味着直接访问属性,并在属性不存在时为您提供编译时错误.

希望这能回答你的问题!

  • `$ .foo`实际上与`self.foo`不同,它是`$(self.foo)` - 也就是说,它逐条列出结果. (9认同)
  • 我已经更新了LIz的答案以包含标量上下文. (3认同)
  • Jonathan ++,我今天学到了一些东西:-)"Itemization"是让"Iterable"不可迭代的过程.例如,如果我们有'我的@a = ^ 5; sub foo(*@ b){dd @b};`和你`foo @ a`你得到`[0,1,2,3,4]`(一个包含5个元素的数组),而如果你逐项列出数组通过调用`.item`方法,就像`foo @ a.item`,你得到`[[0,1,2,3,4],``(所以带有1个元素的数组).你也可以用`$`代替前缀:`foo $ @ a`. (3认同)
  • "逐项化"的含义是什么?你举个例子吗? (2认同)