如何更新作为moose属性的Perl / Tk小部件textvariable?

时间:2014-04-30 19:37:42

标签: perl tk moose

在Perl / Tk中,可以为窗口小部件定义文本变量。它是对一些保持价值的标量的引用。 有人向我展示了如何使用Moose属性强制将Moose属性用作textvariable(很酷!)。这是它的工作原理:

subtype 'TkRef' => as 'ScalarRef';
coerce 'TkRef', from 'Str', via { my $r = $_; return \$r };
has 'some_val' => (is => 'rw', isa => 'TkRef', coerce => 1, default => 'default value');

$mw->Entry(-textvariable => $self->some_val);
$mw->Label(-textvariable => $self->some_val); # will always Show what we type into the entry

但是,当我想为属性设置一个新值时,我必须像这样取消引用它:

${$self->some_val} = 'blarg'; # dereference

简单地设置属性不会起作用,因为引用需要在对象的生命周期内保持不变(即,属性值本身不能更改)。

有没有办法使用漂亮的Moose属性强制功能而不会失去用$self->some_val('blarg');设置属性的可能性?某种反向强制?

1 个答案:

答案 0 :(得分:1)

使访问者保密,然后为访问者提供包装器。像这样:

subtype 'TkRef', as 'ScalarRef';
coerce 'TkRef', from 'Str', via { my $r = $_; return \$r };

has _some_val => (
   is       => 'rw',
   isa      => 'TkRef',
   coerce   => 1,
   init_arg => 'some_val',
   default  => 'default value',
);

sub some_val {
   my $self = shift;
   if (@_ and not ref $_[0]) {
      ${$self->_some_val} = shift;
   }
   elsif (@_ and ref $_[0]) {
      ${$self->_some_val} = ${+shift};
   }
   $self->_some_val(@_);
}