Inheriting private attributes in Perl 6

若如初见. 提交于 2020-01-11 08:16:28

问题


I can't find anything in the docs, but it seems that there is no access in a subclass to its superclass's private variables. Am I right?

class A {
  has $!a;
}

class B is A {
  has $.b;

  method set_a($x) {
    $!a = $x;
  }
}

my $var = B.new();
$var.set_a(5);
say $var.a;

This gives an error message:

Attribute $!a not declared in class B

BTW where to read about Classes in the docs? I have only found a rather short section Classes and Objects.


回答1:


In Perl 6, an attribute declared in a class is accessible only within that class. This means one can confidently refactor the state in the class without having to worry about any uses of that state outside of the class.

Subclasses do not receive any special access with regards to attributes. Some languages provide a protected modifier. This does not exist in Perl 6, by design. Either something is private to that class, or is exposed (like has $.a) to the outside world, since:

  1. So far as that class is concerned, a subclass is part of the outside world.
  2. Given the general advice is to "prefer composition over inheritance", it seems strange to privilege inheritance, or provide a mechanism that frustrates refactoring from inheritance to composition.

Attributes in a role, by contrast, are composed into the class, working as if they had been declared in the class itself. Therefore, an attribute from a composed role may be used in the class body. If looking to write re-usable pieces of functionality in an OO context, it's more typical to use roles and composition in Perl 6, not inheritance. Indeed, writing the original code as:

role A {
  has $!a;
}

class B does A {
  has $.b;

  method set_a($x) {
    $!a = $x;
  }
  method a() { $!a }
}

my $var = B.new();
$var.set_a(5);
say $var.a;

Works as desired.



来源:https://stackoverflow.com/questions/50031400/inheriting-private-attributes-in-perl-6

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!