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

I'm not a terribly experienced programmer so forgive me if this is not a bug, but this is a bug, right? In the Paste subroutine in TableMatrix.pm:
# Paste -- # This procedure pastes the contents of the clipboard to the specified # cell (active by default) in a table widget. # # Arguments: # w - Name of a table widget. # cell - Cell to start pasting in. sub Paste { my $w = shift; my $cell = shift || ''; ## Perltk not sure if translated correctly my $data; if ($cell ne '') { eval{ $data = $w->GetSelection(); }; return if($@); } else { eval{ $data = $w->GetSelection('CLIPBOARD'); }; return if($@); $cell = 'active'; } $w->PasteHandler($w->index($cell),$data); $w->focus if ($w->cget('-state') eq 'normal'); }
In the eval statements I believe there is a bug. The purpose of the statments appears to be to test whether there is a selection available in the Clipboard (on the Clipboard?) and if there isn't, then to just return. because inside the eval statement if there is no selection available in the Clipboard then GetSelection sets the $@ variable, but the return statements are actually outside of the eval statements and at that point $@ is once again empty. So, shouldn't the return statements be inside of the eval statements? Or am I missing the point of the eval statements?

Oh wait! return wouldn't exit the subroutine if it were inside the eval, it only exits the eval, right? I am confused. What is the point of the eval supposed to be?

OK, so I read the man page on eval again, and it looks like the code should work the way it is. But for some reason, $@ does not stay set after leaving the eval block.

I realize now that if GetSelection() did cause an error, then the eval block should be exited immediately with $@ set to the error, correct? THen the code above would work as intended. But for some reason it seems that if GetSelection creates an error due to there being no selection that even though $@ is set, the eval block is not exited. It just continues executing. So the eval block exits normally and $@ is reset to empty.

would this happen because GetSelection is doing something with $SIG{__DIE__}?

Replies are listed 'Best First'.
Re: This is a small bug in TableMatrix.pm, right??
by kyle (Abbot) on Dec 20, 2007 at 19:26 UTC

    A return inside an eval does not return from an enclosing sub. Try it!

    sub eval_return { eval { return; print "This never happens.\n"; }; print "eval did not return from enclosing sub\n"; } eval_return(); __END__ eval did not return from enclosing sub

    The special variable $@ (see perlvar) will always be set after the eval and indicates if the eval encountered an error or died (throwing an exception).

    What's going on in the code you posted is that it's executing the things inside the eval and protecting itself from any errors that might happen inside. If there are some, it returns (return if ($@)) without doing anything else (but it also doesn't die as it would normally without the eval).

Re: This is a small bug in TableMatrix.pm, right??
by gamache (Friar) on Dec 20, 2007 at 19:30 UTC
    eval sets $@ to an error message if the eval'ed block generated an error, and clears $@ otherwise. The eval {...}; if ($@) {...} construct is Perl's version of try and catch.

      OK, I see, but the statment $data = $w->GetSelection() does result in $@ being set inside the eval if there is no selection available. But GetSelection still returns and so the eval executes fine and resets $@ to empty. This must mean that GetSelection() is doing some sort of error trapping of it's own, right?<\p>