gpt4 book ai didi

raku - perl6 上的单例实现

转载 作者:行者123 更新时间:2023-12-01 13:46:27 25 4
gpt4 key购买 nike

我在Rosetta代码上查看了以下代码http://rosettacode.org/wiki/Singleton#Perl_6它在 Perl6 中实现了 Singleton

class Singleton {

has Int $.x is rw;
# We create a lexical variable in the class block that holds our single instance.
my Singleton $instance = Singleton.bless; # You can add initialization arguments here.
method new {!!!} # Singleton.new dies.
method instance { $instance; }
}

my $a=Singleton.bless(x => 1);
my $b=Singleton.bless(x=> 2);


say $a.x;
say $b.x;

#result
# 1
# 2

但似乎使用此实现我可以使用 bless 创建同一类的两个实例,请参见上面的示例,

是否有一个选项可以防止仅实现同一类的一个实例?

最佳答案

Perl 以提供多种做事方式而自豪,让您可以选择适合您的口味和手头应用程序的方式。我这么说是为了强调这是一种简单但可靠的方式,希望它是不言自明的方式 - 我不会将其作为“最佳”方式提出,因为这取决于您的情况。

#!/usr/bin/env perl6

class Scoreboard {
has Str $.home-team ;
has Str $.away-team ;
has Int $.home-score = 0 ;
has Int $.away-score = 0 ;
my Scoreboard $instance;

method new(*%named) {
return $instance //= self.bless(|%named) ;
}

multi method goal($team where * eq $!home-team, Int :$points = 6) {
$!home-score += $points
}

multi method goal($team where * eq $!away-team, Int :$points = 6) {
$!away-score += $points
}

method Str {
"At this vital stage of the game " ~

do given $!home-score <=> $!away-score {
when More {
"$!home-team are leading $!away-team, $!home-score points to $!away-score"
}
when Less {
"$!home-team are behind $!away-team, $!home-score points to $!away-score"
}
default {
"the scores are level! $!home-score apeice!"
}
}
}
}

my $home-team = "The Rabid Rabbits";
my $away-team = "The Turquoise Turtles"; # Go them turtles!

my $scoreboard = Scoreboard.new( :$home-team , :$away-team );

$scoreboard.goal($home-team, :4points) ;
say "$scoreboard";
$scoreboard.goal($away-team) ;
say "$scoreboard";
my $evil_second_scoreboard = Scoreboard.new;
$evil_second_scoreboard.goal($home-team, :2points) ;
say "$evil_second_scoreboard";

这会产生;

At this vital stage of the game The Rabid Rabbits are leading The Turquoise Turtles, 4 points to 0
At this vital stage of the game The Rabid Rabbits are behind The Turquoise Turtles, 4 points to 6
At this vital stage of the game the scores are level! 6 apeice!

这会覆盖默认的 new(通常由类 Mu 提供)并在私有(private) 中保留对我们自己(即此对象)的引用数据。对于私有(private)类数据,我们使用用 my 声明的词法范围标量。 //.defined的运算符形式。因此,在第一次运行时,我们调用 bless 分配对象并初始化属性,然后将其分配给 $instance。在对 new 的后续调用中,定义了 $instance 并立即返回。

如果要防止有人直接调用bless,可以加上;

method bless(|) {
nextsame unless $instance;
fail "bless called on singleton Scoreboard"
}

这将确保只有第一个调用有效。

关于raku - perl6 上的单例实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35676176/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com