绑定标量的构造函数
如果我有一个简单的绑定标量类,每次读取它时都会递增,我可以这样做:
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。看来我可以创建一个像这样的 new
方法:
sub new {
my $class = shift;
my $counter;
tie $counter, $class;
return $counter;
}
然后在我的主脚本中通过执行以下操作获得两个计数器:
my $counter1 = Counter->new();
my $counter2 = Counter->new();
我假设这不起作用,因为领带无法在副本中幸存(我读过在文档中的某处),是否根本没有办法做到这一点?
注意。我知道这只是风格问题,但看起来会更正确。
If I were to have a simple tied scalar class that increments every time it is read I could do that like this:
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;
However to create a counter variable I have to use tie
. I could create one counter and export it. But what I really want to do is make it look OO. It seems that I could create a new
method like this:
sub new {
my $class = shift;
my $counter;
tie $counter, $class;
return $counter;
}
then in my main script get two counters by doing:
my $counter1 = Counter->new();
my $counter2 = Counter->new();
I am assuming this doesn't work because a tie doesn't survive a copy (I read that in the docs somewhere), is there simply no way to do this?
NB. I know it is only a matter of style, but it would LOOK more correct to the eye.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Tie 魔法不会在赋值过程中进行,因为它适用于变量本身,而不是它包含的值。您有几个选择:
返回引用:
分配给 glob:
或者您可以将变量传递到构造函数中:
您甚至可以创建一个适用于这两种方法的构造函数:
在最后两个示例中,
tie
直接传递$_[0]
。原因是@_
的元素是参数列表的别名,因此它的工作方式就像您在tie 中键入
行。my $counter
一样最后,虽然您的示例非常清晰并遵循最佳实践,但本着 TIMTOWTDI 的精神,您可以像这样编写整个课程:
最后要提到的一件事。虽然您的问题是关于绑定变量,但您也可以使用重载来实现此目的:
但是您失去了通过赋值重置计数器的能力。您可以向
Counter
添加一个子集 {$_[0][0] = $_[1]}
方法。Tie magic is not carried across assignment because it applies to the variable itself, not the value it contains. You have a few options:
Returning a reference:
Assigning to a glob:
Or you could pass the variable into the constructor:
You can even make a constructor that works with both methods:
In the last two examples,
tie
is passed$_[0]
directly. The reason for this is that the elements of@_
are aliases to the argument list, so it works as if you had typed themy $counter
in thetie
line.And finally, while your example is very clear and follows best practices, in the spirit of TIMTOWTDI, you could write your entire class like this:
One last thing to mention. While your question is about tied variables, you can also use overloading to achieve this:
But you loose the ability to reset the counter via assignment. You could add a
sub set {$_[0][0] = $_[1]}
method toCounter
.