milma has asked for the wisdom of the Perl Monks concerning the following question:

Could somebody please explain why the expected message is not printed from the code below. I assumed that the regex will return true when a replacement is done, but it makes the replacement and returns false

use strict; use warnings; use Tk; use Tk::BrowseEntry; my %CFG = ( 'target' => 'foobar' ); my $main = MainWindow->new(); my $entry = $main->BrowseEntry( -variable=>\$CFG{target}, ); $entry->grid( -row=>1, -column=>1, ); my $continue = $main->Button( -command=>\&continue, -text=>'run', ); $continue->grid( -row=>2, -column=>1, ); sub continue { warn "$CFG{target}\n"; if ( $CFG{target} =~ s/bar//xms ) { warn "expecting this message\n"; } warn "$CFG{target}\n"; } MainLoop();

Replies are listed 'Best First'.
Re: search and replace regex return value
by shmem (Chancellor) on May 07, 2017 at 10:05 UTC

    Running your code with perl 5.20.2 Tk 804.032 on linux (debian 8) produces:

    foobar expecting this message foo
    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

      I can reproduce with Perl 5.24.1 and Tk 804.033 on Ubuntu. The output of the program after two button clicks is:

      foobar foo foo foo

      Which is strange, since ... =~ s/// is supposed to return the number of substitutions made, and clearly there's one being made here.

      But as I said here, inspecting things with Devel::Peek shows that $CFG{target} appears to have PERL_MAGIC_uvar magic attached to it, so I guess that's causing this strange behavior (haven't yet investigated further).

Re: Tk textvariable search and replace regex return value
by Anonymous Monk on May 07, 2017 at 10:15 UTC

    Could somebody please explain why the expected message is not printed from the code below. I assumed that the regex will return true when a replacement is done, but it makes the replacement and returns false

    I assume it has to do with the value being a textvariable

    Workaround is simple

    my $target = $CFG{target} ; if ( $target =~ s/bar//xms ) { warn "expecting this message\n"; $CFG{target} = $target; } else { warn "not expecting this message\n"; }
Re: search and replace regex return value
by milma (Initiate) on May 07, 2017 at 14:02 UTC

    The issue is visible on perl 5.22.0, Tk 804.033 running in CentOS 6.8. Based on the fact that older version gives "correct" result I can only assume that I have a faulty version and I'll need to update to latest available and see if it fixes the issue.

        Could it be a blessed object or something else?

        I think the AM post is onto something, Devel::Peek shows that $CFG{target} has some magic of type PERL_MAGIC_uvar attached to it. Not being a Tk expert I can only guess that the magic is probably necessary to bind the value to the widget, but the fact that this causes $CFG{target} =~ ... to behave differently than usual smells like a bug to me. But if the app needs to work on a range of Tk versions, it looks like the workaround might be necessary.

      The problem does not exist with perl version 5.24.1 and also the workaround

      my $target = $CFG{target} ;

      resolves the issue in version 5.22, so I have alternative ways to resolve my issue. Thanks for your help.