无法用祝福方法设置属性
我认为可能是一个怪异的情况。没有把握。但是我有这个:
class Y {
has Int $.vol;
has Str $.quant;
has Str $.abbr;
submethod BUILD(
Str :$!abbr,
Int :$!vol,
) { }
}
class X is Y {
multi method new(Int:D :$vol) {
self.bless(
:$vol,
:abbr('C'),
);
}
multi method new(Str:D :$quant) {
self.bless(
:$quant,
:abbr('C'),
);
}
}
my $x = X.new(vol => 7);
say $x;
# OUTPUT: X.new(vol => 7, abbr => "C")
这是预期的。 abbr
属性被填充。但是,在下面的代码中,我无法获得abbr
填充:
#!/usr/bin/env raku
use v6.d;
use Lingua::EN::Numbers;
constant Nᴀ = 602214076000000000000000;
class Mass-t { ... }
class Mass-kg { ... }
class Mass-g { ... }
class Mass-mg { ... }
class Mass-ug { ... }
class Mass-mcg { ... }
class Mass-oz { ... }
class Mass-lb { ... }
class Mass-c { ... }
class Volume-m { ... }
class Volume-cm { ... }
class Volume-mm { ... }
class Length-cm { ... }
class Length-m { ... }
class Length-mm { ... }
class Quantity-mol { ... }
class Quantity-dz { ... }
class Substance-c { ... }
class Substance-air { ... }
class Volume { ... }
END {
my $v = Quantity-mol.new(1.0);
my $c = Substance-c.new(quant => $v);
say $c;
say 'done with program';
exit;
}
class Quantity {
has Str $.name;
has Str $.abbr is rw;
has Rat $.value;
has Rat $.base_value;
submethod BUILD(Rat :$!value,
Str :$!name,
Str :$!abbr,
Rat :$!base_value,
) { }
method get_value() {
return $!value ~ ' ' ~ $!abbr;
}
method count(Bool:D $comma = True) {
return comma $!value * $!base_value if $comma;
return $!value * $!base_value;
}
method to(Str:D $abbr-in) {
my $class = split('-', self.^name)[0];
my $abbr = $abbr-in.lc;
my $to = ::("$class-$abbr").new();
self!convert($to);
}
method !convert(Quantity:D $to) {
my $result = comma (self.count(False) / $to.base_value);
return $result ~ ' ' ~ $to.abbr;
}
}
class Quantity-mol is Quantity {
method new(Rat:D() $value = 1.0) {
self.bless(
:name('mole'),
:abbr('㏖'),
:base_value(Rat.new(Nᴀ, 1)),
:$value,
);
}
}
class Quantity-dz is Quantity {
method new(Rat:D() $value = 1.0) {
self.bless(
:base_value(12.0),
:name('dozen'),
:abbr('dz'),
:$value,
);
}
}
class Measure {
has Str $!name;
has Str $.abbr is rw;
has Rat $.value;
has Rat $.base_value;
has Rat $.imp_base_value;
submethod BUILD(Rat :$!value,
Str :$!name,
Str :$!abbr,
Rat :$!base_value,
Rat :$!imp_base_value,
) { }
method to(Str:D $abbr-in) {
my $class = split('-', self.^name)[0];
my $abbr = $abbr-in.lc;
my $to = ::("$class-$abbr").new();
self!convert($to)
}
method !convert(Measure:D $to) {
my $imp_conv = $.imp_base_value && $to.imp_base_value;
my $base_value = $imp_conv ?? $.imp_base_value !! $.base_value;
my $to_base_value = $imp_conv ?? $to.imp_base_value !! $to.base_value;
my $conversion = ($.value * $base_value) / $to_base_value;
my $num = $conversion > 1 ?? comma ($conversion) !! $conversion < 1/10000 ?? (sprintf "%.5e", $conversion) !! $conversion;
# do pretty scientific notation
if $conversion < 1 / 10000 {
my $exp = $num ~~ / '-' 0* <(\d+)>$/;
$exp .= trans( '0123456789' => '⁰¹²³⁴⁵⁶⁷⁸⁹' );
$num .= subst(/e\-\d+/, "\x[00D7]10\x[207B]$exp");
}
return $num ~ ' ' ~ $to.abbr;
}
method !count {
}
}
class Mass is Measure { }
class Length is Measure { }
class Substance {
has Quantity-mol $.quant;
has Volume $.vol;
has Str $.abbr is rw;
submethod BUILD(Quantity-mol :$!quant,
Volume :$!vol,
Str :$!abbr,
) { }
method volume() {
return $.vol.value ~ ' ' ~ $.vol.abbr;
}
method moles() {
return $.quant.value ~ ' ' ~ $.quant.abbr ~ ' ' ~ $.abbr;
}
}
class Substance-co2 is Substance {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm'),
:$value,
);
}
}
class Substance-c is Substance {
multi method new(Volume:D $vol) {
self.bless(
:$vol,
:abbr('C'),
);
}
multi method new(Quantity-mol:D $quant) {
self.bless(
:$quant,
:abbr('C'),
);
}
}
class Substance-air is Substance {
}
class Length-cm is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm'),
:base_value(1/100),
:$value,
);
}
}
class Length-m is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('m'),
:base_value(1.0),
:$value,
);
}
}
class Length-mm is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mm'),
:base_value(1/1000),
:$value,
);
}
}
class Volume is Measure {
has Str $.abbr;
has Rat $.base_value;
has Rat $.value;
}
class Volume-m is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('m³'),
:base_value(1.0),
:$value,
);
}
}
class Volume-cm is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm³'),
:base_value(1 / 1_000_000),
:$value,
);
}
}
class Volume-l is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('l'),
:base_value(1 / 1_000),
:$value,
);
}
}
class Volume-ml is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('ml'),
:base_value(1 / 1_000_000),
:$value,
);
}
}
class Volume-mm is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mm³'),
:base_value(1 / 1_000_000_000),
:$value,
);
}
}
class Density {
has Mass $.mass;
has Volume $.volume;
method calculate() {
return $.mass / $.volume;
}
}
class Density-water {
method new(Rat:D()) {
self.bless(
:mass(Mass-kg.new()),
:volume(Volume-l.new()),
);
}
}
class Mass-c is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g/mol'),
:base_value(12.0107),
:$value,
);
}
}
class Mass-air is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g/mol'),
:base_value(28.9647),
:$value,
);
}
}
class Mass-Da is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('Da'),
:base_value(Rat.new(1, 602214075789225073400000)),
:$value,
);
}
}
class Mass-kg is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('kg'),
:base_value(1000.0),
:$value,
);
}
}
class Mass-oz is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('oz'),
:base_value(28.3495231),
:imp_base_value(1/16),
:$value,
);
}
}
class Mass-lb is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('lb'),
:base_value(453.59237),
:imp_base_value(1.0),
:$value,
);
}
}
# lb aliases
class Mass-g is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g'),
:base_value(1.0),
:$value,
);
}
}
class Mass-mg is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mg'),
:base_value(1/1000),
:$value,
);
}
}
class Mass-ug is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('µg'),
:base_value(1/1_000_000),
:$value,
);
}
}
class Mass-mcg is Mass-ug {
method TWEAK { $.abbr = "mcg" }
}
class Mass-mt is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mt'),
:base_value(1_000_000.0),
:$value,
);
}
}
class Mass-gt is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mt'),
:base_value(1_000_000_000_000.0),
:$value,
);
}
}
class Mass-t is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('t'),
:base_value(907184.74),
:$value,
);
}
}
此输出:
Substance-c.new(quant => Quantity-mol.new(name => "mole", abbr => "㏖", value => 1.0, base_value => 602214076000000000000000.0), vol => Volume, abbr => Str)
请注意,abbr
属性永远不会设置。只是说str
(请务必一直向右滚动以查看此内容)。我已经盯着这个了很长时间了,无法弄清楚发生了什么。
Got a weird situation I think might be a bug. Not sure. But I have this:
class Y {
has Int $.vol;
has Str $.quant;
has Str $.abbr;
submethod BUILD(
Str :$!abbr,
Int :$!vol,
) { }
}
class X is Y {
multi method new(Int:D :$vol) {
self.bless(
:$vol,
:abbr('C'),
);
}
multi method new(Str:D :$quant) {
self.bless(
:$quant,
:abbr('C'),
);
}
}
my $x = X.new(vol => 7);
say $x;
# OUTPUT: X.new(vol => 7, abbr => "C")
This works as expected. The abbr
attribute is populated. However, in the code below, I can't get the abbr
to populate:
#!/usr/bin/env raku
use v6.d;
use Lingua::EN::Numbers;
constant Nᴀ = 602214076000000000000000;
class Mass-t { ... }
class Mass-kg { ... }
class Mass-g { ... }
class Mass-mg { ... }
class Mass-ug { ... }
class Mass-mcg { ... }
class Mass-oz { ... }
class Mass-lb { ... }
class Mass-c { ... }
class Volume-m { ... }
class Volume-cm { ... }
class Volume-mm { ... }
class Length-cm { ... }
class Length-m { ... }
class Length-mm { ... }
class Quantity-mol { ... }
class Quantity-dz { ... }
class Substance-c { ... }
class Substance-air { ... }
class Volume { ... }
END {
my $v = Quantity-mol.new(1.0);
my $c = Substance-c.new(quant => $v);
say $c;
say 'done with program';
exit;
}
class Quantity {
has Str $.name;
has Str $.abbr is rw;
has Rat $.value;
has Rat $.base_value;
submethod BUILD(Rat :$!value,
Str :$!name,
Str :$!abbr,
Rat :$!base_value,
) { }
method get_value() {
return $!value ~ ' ' ~ $!abbr;
}
method count(Bool:D $comma = True) {
return comma $!value * $!base_value if $comma;
return $!value * $!base_value;
}
method to(Str:D $abbr-in) {
my $class = split('-', self.^name)[0];
my $abbr = $abbr-in.lc;
my $to = ::("$class-$abbr").new();
self!convert($to);
}
method !convert(Quantity:D $to) {
my $result = comma (self.count(False) / $to.base_value);
return $result ~ ' ' ~ $to.abbr;
}
}
class Quantity-mol is Quantity {
method new(Rat:D() $value = 1.0) {
self.bless(
:name('mole'),
:abbr('㏖'),
:base_value(Rat.new(Nᴀ, 1)),
:$value,
);
}
}
class Quantity-dz is Quantity {
method new(Rat:D() $value = 1.0) {
self.bless(
:base_value(12.0),
:name('dozen'),
:abbr('dz'),
:$value,
);
}
}
class Measure {
has Str $!name;
has Str $.abbr is rw;
has Rat $.value;
has Rat $.base_value;
has Rat $.imp_base_value;
submethod BUILD(Rat :$!value,
Str :$!name,
Str :$!abbr,
Rat :$!base_value,
Rat :$!imp_base_value,
) { }
method to(Str:D $abbr-in) {
my $class = split('-', self.^name)[0];
my $abbr = $abbr-in.lc;
my $to = ::("$class-$abbr").new();
self!convert($to)
}
method !convert(Measure:D $to) {
my $imp_conv = $.imp_base_value && $to.imp_base_value;
my $base_value = $imp_conv ?? $.imp_base_value !! $.base_value;
my $to_base_value = $imp_conv ?? $to.imp_base_value !! $to.base_value;
my $conversion = ($.value * $base_value) / $to_base_value;
my $num = $conversion > 1 ?? comma ($conversion) !! $conversion < 1/10000 ?? (sprintf "%.5e", $conversion) !! $conversion;
# do pretty scientific notation
if $conversion < 1 / 10000 {
my $exp = $num ~~ / '-' 0* <(\d+)>$/;
$exp .= trans( '0123456789' => '⁰¹²³⁴⁵⁶⁷⁸⁹' );
$num .= subst(/e\-\d+/, "\x[00D7]10\x[207B]$exp");
}
return $num ~ ' ' ~ $to.abbr;
}
method !count {
}
}
class Mass is Measure { }
class Length is Measure { }
class Substance {
has Quantity-mol $.quant;
has Volume $.vol;
has Str $.abbr is rw;
submethod BUILD(Quantity-mol :$!quant,
Volume :$!vol,
Str :$!abbr,
) { }
method volume() {
return $.vol.value ~ ' ' ~ $.vol.abbr;
}
method moles() {
return $.quant.value ~ ' ' ~ $.quant.abbr ~ ' ' ~ $.abbr;
}
}
class Substance-co2 is Substance {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm'),
:$value,
);
}
}
class Substance-c is Substance {
multi method new(Volume:D $vol) {
self.bless(
:$vol,
:abbr('C'),
);
}
multi method new(Quantity-mol:D $quant) {
self.bless(
:$quant,
:abbr('C'),
);
}
}
class Substance-air is Substance {
}
class Length-cm is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm'),
:base_value(1/100),
:$value,
);
}
}
class Length-m is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('m'),
:base_value(1.0),
:$value,
);
}
}
class Length-mm is Length {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mm'),
:base_value(1/1000),
:$value,
);
}
}
class Volume is Measure {
has Str $.abbr;
has Rat $.base_value;
has Rat $.value;
}
class Volume-m is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('m³'),
:base_value(1.0),
:$value,
);
}
}
class Volume-cm is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('cm³'),
:base_value(1 / 1_000_000),
:$value,
);
}
}
class Volume-l is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('l'),
:base_value(1 / 1_000),
:$value,
);
}
}
class Volume-ml is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('ml'),
:base_value(1 / 1_000_000),
:$value,
);
}
}
class Volume-mm is Volume {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mm³'),
:base_value(1 / 1_000_000_000),
:$value,
);
}
}
class Density {
has Mass $.mass;
has Volume $.volume;
method calculate() {
return $.mass / $.volume;
}
}
class Density-water {
method new(Rat:D()) {
self.bless(
:mass(Mass-kg.new()),
:volume(Volume-l.new()),
);
}
}
class Mass-c is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g/mol'),
:base_value(12.0107),
:$value,
);
}
}
class Mass-air is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g/mol'),
:base_value(28.9647),
:$value,
);
}
}
class Mass-Da is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('Da'),
:base_value(Rat.new(1, 602214075789225073400000)),
:$value,
);
}
}
class Mass-kg is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('kg'),
:base_value(1000.0),
:$value,
);
}
}
class Mass-oz is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('oz'),
:base_value(28.3495231),
:imp_base_value(1/16),
:$value,
);
}
}
class Mass-lb is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('lb'),
:base_value(453.59237),
:imp_base_value(1.0),
:$value,
);
}
}
# lb aliases
class Mass-g is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('g'),
:base_value(1.0),
:$value,
);
}
}
class Mass-mg is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mg'),
:base_value(1/1000),
:$value,
);
}
}
class Mass-ug is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('µg'),
:base_value(1/1_000_000),
:$value,
);
}
}
class Mass-mcg is Mass-ug {
method TWEAK { $.abbr = "mcg" }
}
class Mass-mt is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mt'),
:base_value(1_000_000.0),
:$value,
);
}
}
class Mass-gt is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('mt'),
:base_value(1_000_000_000_000.0),
:$value,
);
}
}
class Mass-t is Mass {
method new(Rat:D() $value = 1.0) {
self.bless(
:abbr('t'),
:base_value(907184.74),
:$value,
);
}
}
This outputs:
Substance-c.new(quant => Quantity-mol.new(name => "mole", abbr => "㏖", value => 1.0, base_value => 602214076000000000000000.0), vol => Volume, abbr => Str)
Note here the abbr
attribute never gets set. It's just says Str
(be sure to scroll all the way to the right to see this). I've been staring at this for a long time and cannot figure it out what's going on.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为了获得答案,如果您要高尔夫球尽可能小,这将有所帮助。
无论如何,问题实际上是您尝试创建
quents
对象的方式。您在
senterance-c
中使用位置创建了一个新的候选人:因此,如果将调用更改为:
您从事业务。
那么为什么这不创建错误呢?这是因为您打电话给它的方式使用默认
new
(系统提供),该仅使用命名参数。因此,它没有调用您提供的任何新的方法。另一个注意:为什么所有
构建
方法?据我所知,在您的示例中不需要它们。To get answers on SO, it would help if you would golf your code to be as small as possible.
Anyways, the problem is really in the way that you try to create the
Substance
object.You created a
new
candidate inSubstance-c
with a positional:So if you change the call to:
you are in business.
So why doesn't this create an error? That's because the way you called it, uses the default
new
(provided by the system), which only takes named arguments. So it was not calling any of thenew
methods you provided.One further note: why all the
BUILD
methods? None of them are needed in your example, as far as I can see.