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


如果我有一个公共方法,我可以使用它们在类中调用它 $.name 和 self.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

但是,如果我做 b 私有方法,我只能用它来调用它 self!b不是 $!b,否则我收到以下错误信息:

Attribute $!b not declared in class TEST

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


9061
2018-04-22 20:40


起源

我认为以下是正确的。我希望它有用。 $!bar, $!baz等等总是指的 私人属性。总是。 Atrributes是总是 私人即使医生另有说法。 foo!bar 要么 !bar  总是 是指私人 方法,不属性(虽然他们的代码可以)。 foo.bar 要么 .bar  总是 指的是一种公共方法。 决不 写 foo.bar(...) 要么 .bar(...) 使用公共访问器来获取或设置私有属性的值;而只是写 foo.bar 要么 .bar 阅读和 foo.bar = ... 要么 .bar = 获取或设置的值 foo的 $!bar 属性。 - raiph
如果您需要可以设置私有属性的公共访问者,请确保添加 is rw 属性的声明。 - raiph


答案:


属性总是可以称为 $!foo 在课堂上。如果你这样做,那么生成的代码将直接访问属性本身,并且任何继承类的类都会  能够改变这种行为。

如果你使用 has $.foo 在一个类的声明中,它意味着一个公共访问器(如果你添加 is rw 它也可以作为一个变异器)。

当你使用 $.foo 在你的代码中,否则就是 究竟 同样的 $( self.foo )。这意味着它将调用该方法 foo 上 self,并逐项列出返回值(如果还没有,则将其作为单个“事物”)。如果您使用定义属性,则会出错 $!foo 而且你没有提供 method foo 你自己。

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

如果您定义私有方法 !baz! 只是表明方法的隐私,这意味着你需要将其称为 self!baz。有 没有 它的简短语法。

我个人不喜欢你可以说的事实 $.zippo 即使 zippo 不是属性。但我担心这艘船已驶过。但这种行为现在引起你的困惑:-(

那么,为了调用私有方法没有简短的语法规则背后的原因是什么?不确定,我想是的 $!foo 已经被认为是指对属性的直接访问,如果该属性不存在,则会为您提供编译时错误。

希望这能回答你的问题!


10
2018-04-22 22:05



$.foo 实际上并不是一样的 self.foo, 它的 $(self.foo)  - 也就是说,它逐条列出结果。 - Jonathan Worthington
我已经更新了LIz的答案以包含标量上下文。 - moritz
“逐项化”的含义是什么?你举个例子吗? - Eugene Barsky
Jonathan ++,我今天学到了一些东西:-)“Itemization”是制作东西的过程 Iterable 非迭代。例如,如果我们有 my @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。 - Elizabeth Mattijsen
谢谢!我希望,现在我更了解它。 - Eugene Barsky