【问题标题】:How to update a Perl/Tk widget textvariable that is a moose attribute?如何更新作为 moose 属性的 Perl/Tk 小部件文本变量?
【发布时间】:2014-04-30 19:37:41
【问题描述】:

在 Perl/Tk 中,可以为小部件定义文本变量。它是对保存该值的某个标量的引用。 有人向我展示了如何使用 Moose 属性强制将 Moose 属性用作文本变量(酷!)。它是这样工作的:

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'); 设置属性的可能性?某种反向强制?

【问题讨论】:

    标签: perl tk moose


    【解决方案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(@_);
    }
    

    【讨论】:

    • 这太酷了。尽管类型强制让我想起了其他编程语言的类型转换东西——这是我不知道的,这也是我最终选择 Perl 的原因——它正是我想要它做的事情。现在剩下的就是封装它,这样我就不必每次有这样的变量时都查看/编写它。
    猜你喜欢
    • 2021-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 1970-01-01
    • 2011-04-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多