gpt4 book ai didi

perl - 绑定(bind)标量的构造函数

转载 作者:行者123 更新时间:2023-12-02 15:18:40 25 4
gpt4 key购买 nike

如果我有一个简单的绑定(bind)标量类,每次读取时都会递增,我可以这样做:

package Counter;

use strict;
use warnings;

sub TIESCALAR {
my $class = shift;
my $value = 0;

bless \$value, $class;

return \$value;
}

sub FETCH {
my $self = shift;

my $value = $$self;

$$self++;

return $value;
}

sub STORE {
my $self = shift;
$$self = shift;
}

1;

但是,要创建计数器变量,我必须使用tie。我可以创建一个计数器并将其导出。但我真正想做的是让它看起来 OO。看来我可以创建一个新的方法,如下所示:

sub new {
my $class = shift;
my $counter;

tie $counter, $class;

return $counter;
}

然后在我的主脚本中通过执行以下操作获取两个计数器:

my $counter1 = Counter->new();
my $counter2 = Counter->new();

我假设这不起作用,因为领带无法在副本中保存下来(我在某处的文档中读到了这一点),是否根本没有办法做到这一点?

注意。我知道这只是风格问题,但看起来会更正确。

最佳答案

Tie 魔法不会在赋值过程中进行,因为它适用于变量本身,而不是它包含的值。您有几个选择:

返回引用:

sub new {tie my $ret, ...; \$ret}

my $counter = Counter->new;

say $$counter;

分配给 glob:

our ($counter);

*counter = Counter->new; # same new as above

say $counter;

或者您可以将变量传递到构造函数中:

sub new {my $class = shift; tie $_[0], $class}

Counter->new(my $counter);

say $counter;

您甚至可以创建一个适用于这两种方法的构造函数:

sub new {
my $class = shift;
tie $_[0] => $class;
\$_[0]
}

our $glob; *glob = Counter->new;

Counter->new(my $lexical);

在最后两个示例中,tie 直接传递$_[0]。原因是 @_ 的元素是参数列表的别名,因此它的工作方式就像您在 tie 中键入 my $counter 一样 行。

<小时/>

最后,虽然您的示例非常清晰并遵循最佳实践,但本着 TIMTOWTDI 的精神,您可以像这样编写整个类(class):

{package Counter;
sub TIESCALAR {bless [0]}
sub FETCH {$_[0][0]++}
sub STORE {$_[0][0] = $_[1]}
sub new {tie $_[1] => $_[0]; \$_[1]}
}
<小时/>

最后一件事要提。虽然您的问题是关于绑定(bind)变量,但您也可以使用重载来实现此目的:

{package Counter;
use overload fallback => 1, '""' => sub {$_[0][0]++};
sub new {bless [0]}
}

my $counter = Counter->new; # overloading survives the assignment

say $counter;

但是您失去了通过分配重置计数器的能力。您可以向 Counter 添加一个子集 {$_[0][0] = $_[1]} 方法。

关于perl - 绑定(bind)标量的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4905060/

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