作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试“覆盖” raku 为公共(public) $ 生成的内置访问器。属性。但是,我可以使用一些帮助来尝试找出此代码失败的原因......
class Measure {
has $.value is rw
}
class Angle is Measure {
multi method value( $x ) {
nextwith( $x % 360 );
}
}
my $m = Measure.new( value => 27 );
$m.value = 42;
say $m; #Measure.new(value => 42)
my $a = Angle.new( value => 27 );
$a.value = 43;
say $a; #Error...
Cannot resolve caller value(Angle:D: ); none of these signatures match:
(Angle: $x, *%_)
您的指导将非常有帮助!
最佳答案
当您使用 .
将属性声明为公共(public)时, Raku 将创建一个具有相同名称的方法。
该方法不接受任何参数。
就算是rw
.
(如果您将属性声明为 is rw
,则生成的方法实际上是用 is rw
标记的。)
当您使用 nextwith
它分派(dispatch)给父类中的方法。
在这种情况下,该方法不接受任何参数。
这是至少有效的东西:
class Angle is Measure {
method value( $x ) {
callwith() = $x % 360;
}
}
my $a = Angle.new( value => 27 );
#$a.value = 43;
$a.value(43);
当然这意味着
Angle.value
不是像
Measure.value
这样的左值是。
=
的左侧。)
.value
时进行计算我们需要返回一个
Proxy
class Angle is Measure {
method value() is rw {
Proxy.new:
FETCH => -> $ { self.Measure::value },
STORE => -> $, $x {
self.Measure::value = $x % 360;
}
}
}
请注意,我们不能只使用
callsame
或在这些 block 中类似,因为它们启动了一个新的调度链。
Measure
中的方法版本。类(class)。
callsame
或类似的,如果您将该调用的结果绑定(bind)到您用作闭包的一部分的变量。
$attr
因为它绑定(bind)到实际的属性标量。)
class Angle is Measure {
method value is rw {
my $attr := callsame();
Proxy.new:
FETCH => -> $ { $attr },
STORE => -> $, $x {
$attr = $x % 360;
}
}
}
Measure
可能应该是一个角色,因为这使事情变得更容易,因为您可以直接访问该属性。
role Measure {
has $.value is rw
}
class Angle does Measure {
method value() {
Proxy.new:
FETCH => -> $ { $!value },
STORE => -> $, $x {
$!value = $x % 360;
}
}
}
role Measure {
has Real $.value is rw;
}
role Angle {…}
class Degrees {…}
class Radians {…}
class Gradians {…}
role Angle does Measure {
method Degrees ( --> Degrees ) {…}
method Radians ( --> Radians ) {…}
method Gradians ( --> Gradians ) {…}
}
class Degrees does Angle {
method value() {
Proxy.new:
FETCH => -> $ { $!value },
STORE => -> $, $x {
$!value = $x % 360;
}
}
method Degrees () { self }
method Radians () { !!! } # needs to actually be implemented here
method Gradians () { !!! }
}
class Radians does Angle {
method value() {
Proxy.new:
FETCH => -> $ { $!value },
STORE => -> $, $x {
$!value = $x % τ;
}
}
method Degrees () { !!! }
method Radians () { self }
method Gradians () { !!! }
}
class Gradians does Angle {
method value() {
Proxy.new:
FETCH => -> $ { $!value },
STORE => -> $, $x {
$!value = $x % 400;
}
}
method Degrees () { !!! }
method Radians () { !!! }
method Gradians () { self }
}
老实说,我也不喜欢这样,因为您将值视为容器。
class Foo {
has Angle $.bar;
}
my $foo = Foo.new( bar => Degrees.new( value => 27 ) );
$foo.bar.angle = 43;
我认为您应该要求它像这样工作,您可以在其中选择角度是否恒定。
class Foo {
has Angle $.bar is rw;
}
my $foo = Foo.new( bar => Degrees.new( value => 27 ) );
$foo.bar .= new( value => 43 );
这样做可以让您直接删除
value
所有子类中的方法,并用简单的
TWEAK
替换它们.
is rw
来自
$.value
.
.new
只有一个值,而不是
value => 27
.
role Measure {
has Real $.value;
multi method new ( $value ) {
samewith( :$value )
}
}
role Angle {…}
class Degrees {…}
class Radians {…}
class Gradians {…}
role Angle does Measure {
method Degrees ( --> Degrees ) {…}
method Radians ( --> Radians ) {…}
method Gradians ( --> Gradians ) {…}
}
class Degrees does Angle {
submethod TWEAK { $!value %= 360 }
method Degrees () { self }
method Radians () { !!! } # needs to actually be implemented here
method Gradians () { !!! }
}
class Radians does Angle {
submethod TWEAK { $!value %= τ }
method Degrees () { !!! }
method Radians () { self }
method Gradians () { !!! }
}
class Gradians does Angle {
submethod TWEAK { $!value %= 400 }
method Degrees () { !!! }
method Radians () { !!! }
method Gradians () { self }
}
class Foo {
has Angle $.bar is rw;
}
my $foo = Foo.new( bar => Degrees.new( 27 ) );
$foo.bar = Degrees.new( 43 );
关于最后一个版本,我希望您注意一些事情。
!!!
填写这些部分,但那里不应该有太多代码。)
Proxy
],但它更难是有原因的。
关于oop - raku 内置访问器方法可以被子类覆盖吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63972365/
我是一名优秀的程序员,十分优秀!