How to update a Perl/Tk widget textvariable that is a moose attribute?

淺唱寂寞╮ 提交于 2019-12-24 00:56:05

问题


In Perl/Tk, one can define textvariables for widgets. It's a reference to some scalar that holds the value. Someone showed me how to use Moose attribute coercion to use Moose attributes as textvariable (cool!). This is how it works:

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

However, when I want to set a new value for the attribute, I have to dereference it like this:

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

Simply setting the attribute won't work, as the reference needs to remain the same over the life of the object (that is, the attribute value itself cannot change).

Is there a way to use the nice Moose attribute coerce feature without losing the possibility to set the attribute with $self->some_val('blarg'); ? Some sort of reverse-coercion?


回答1:


Make the accessors private, and then provide a wrapper for the accessor. Something like this:

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(@_);
}


来源:https://stackoverflow.com/questions/23396627/how-to-update-a-perl-tk-widget-textvariable-that-is-a-moose-attribute

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!