Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/drupal/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何更新作为moose属性的Perl/Tk小部件textvariable?_Perl_Tk_Moose - Fatal编程技术网

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

如何更新作为moose属性的Perl/Tk小部件textvariable?,perl,tk,moose,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'

在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
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(@_);
}
简单地设置属性是行不通的,因为引用需要在对象的整个生命周期内保持不变(也就是说,属性值本身不能更改)


有没有一种方法可以在不丢失使用
$self->some_val('blarg')设置属性的可能性的情况下使用尼斯驼鹿属性强制功能?某种类型的反向强制?

使访问器私有,然后为访问器提供包装。大概是这样的:

${$self->some_val} = 'blarg'; # dereference
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(@_);
}

这太酷了。尽管类型强制让我想起了其他编程语言中的类型强制(我不这么做,这也是我选择Perl的原因),但它确实做了我希望它做的事情。现在剩下的就是封装它,这样我就不必每次有这样一个变量时都看到/写入它。