你如何在perl中锁定成员变量?

时间:2013-12-07 22:11:02

标签: perl

我在perl中编写了一个执行多线程的脚本,然后尝试将其转换为对象。但是,我似乎无法弄清楚如何锁定成员变量。我最接近的是:

#!/usr/bin/perl
package Y;
use warnings;
use strict;
use threads;
use threads::shared;

sub new
{
  my $class = shift;
  my $val :shared = 0;
  my $self =
  {
    x => \$val
  };
  bless $self, $class;
  is_shared($self->{x}) or die "nope";
  return $self;
}

package MAIN;
use warnings;
use strict;
use threads;
use threads::shared;
use Data::Dumper;

my $x = new Y();
{
  lock($x->{x});
}
print Dumper('0');                 # prints: $VAR = '0';
print Dumper($x->{x});             # prints: $VAR = \'0';
print "yes\n" if ($x->{x} == 0);   # prints nothing
#print "yes\n" if ($$x->{x} == 0);  # dies with msg: Not a SCALAR reference
my $tmp = $x->{x};                 # this works.  Must be a order of precedence thing.
print "yes\n" if ($$tmp == 0);     # prints: yes


#++$$x->{x};                        # dies with msg: Not a SCALAR reference
++$$tmp;
print Dumper($x->{x});             # prints: $VAR = \'1';

这允许我锁定成员var x,但这意味着我需要2个成员变量,因为实际的成员var实际上不能通过赋值来操作,递增它等我甚至无法对它进行测试。

修改

我在想我应该重命名这个问题“你如何取消引用perl中的成员变量?”因为问题似乎归结为此。使用$$x->{x}语法无效,您不能强制使用括号的优先级规则。即$($x->{x})不起作用。使用临时工作,但这是一个麻烦。

1 个答案:

答案 0 :(得分:2)

我没有得到你想要做的线程和锁定,但是你使用引用的方式有一些简单的错误。

$x->{x}

是对标量的引用,因此表达式

$x->{x} == 0
++$$x->{x}
看起来都很可疑。 $$x->{x}被解析为{$$x}->{x}(取消引用$x,然后将其视为哈希引用,并使用键x查找该值。我想你的意思是说

${$x->{x}} == 0
++${$x->{x}}

其中${$x->{x}}表示将$x视为哈希引用,在该哈希中查找键x的值,然后取消该值。