Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options

Re^7: tk option+value in variable?

by cniggeler (Sexton)
on Jan 28, 2019 at 16:45 UTC ( [id://1229076] : note . print w/replies, xml ) Need Help??

in reply to Re^6: tk option+value in variable?
in thread tk option+value in variable?

Thanks again! By reducing to a simpler example, I now see that eval("$x + $y") and eval('$x + $y') are both evaluated by, er, eval. I had played with eval originally because I thought eval($mw->Label(-text => "Col. 1", $opt, -padx => 10)->grid( ...) would substitute $opt with its contents, and in turn evaluate the entire string. I still don't understand the steps the interpreter takes when processing an eval, but it's probably not a fruitful path to pursue further at this time. Better that I understand now that since subroutines take lists as their argument, @opt is an appropriate means to convey list items.

Replies are listed 'Best First'.
Re^8: tk option+value in variable?
by haukex (Archbishop) on Jan 28, 2019 at 18:32 UTC
    I still don't understand the steps the interpreter takes when processing an eval

    eval with a string argument basically does the same thing as perl when it parses and executes Perl code. The thing that can get confusing is exactly what the contents of that string are. Consider this: when you write $x=3; $y=2; print "$x + $y";, then you know that double quotes interpolate, in this case meaning that the current values of those variables are substituted into the string. What gets passed to the print function is the string "3 + 2". On the other hand, in print '$x + $y';, the single quotes don't interpolate, and the string that gets passed to the function is exactly '$x + $y'. Now substitute eval for print, and I hope it's clear what strings are being passed to the function: In the first case, eval is parsing and executing the Perl code 3 + 2, and in the second case, it's parsing and executing the Perl code $x + $y, with the current values of those variables. Although in this simple example the result may be the same, it can get very tricky very quickly, for example if the code and especially the contents of the variables get more complex, if the string to be evaled gets stored for later execution, and so on.

Re^8: tk option+value in variable?
by AnomalousMonk (Archbishop) on Jan 28, 2019 at 20:05 UTC

    Further to haukex's post++, here's an untested way your original approach might have been made to work. Please understand that I only suggest this for the purpose of experimenting to gain a better understanding of eval when you meet it again.

    The basic idea here is to completely build and possibly check the eval string before passing it to eval.

    my $newfont = ...; my ($fg, $bg) = (..., ...); my $opt = "-fg => $fg, -bg => $bg"; $opt .= ", -font => $newfont" if length $newfont; my $eval_string = # note \$rw is escaped, $opt is NOT qq{\$rw->Label(-text => "Col. 1", $opt, -padx => 10)->grid( \$rw->Label(-text => "Col. 2", $opt, -padx => 11), \$rw->Label(-text => "Col. 3", $opt, -padx => 11)) }; print "eval string '$eval_string' \n" if $DEBUG; my $rw = ...; # tk object must exist before string is eval-ed eval $eval_string;
    Again, Don't Do This! in your Tk app: you'll give yourself a terrible headache. eval is powerful and can be very useful, but there's a time and place for everything.

    Just to pound this completely into the ground, if $opt had been something that made sense to Label (so you didn't get the "Odd number of args ..." or any other error), why couldn't
        eval($mw->Label(-text => "Col. 1", $opt, -padx => 10)->grid( ...));
    work? It might, or at least it might appear to.

    In the  eval EXPR invocation above, the expression is
        $mw->Label(-text => "Col. 1", $opt, -padx => 10)->grid( ...)
    and the value passed to eval depends on whatever the call to  grid() returns, which, IIRC, is nothing, the empty list (but I haven't checked this). In this case, the call to Label might work as expected when it was invoked during construction of the eval argument list, but when the (I think) empty argument list was then passed to eval, a perhaps puzzling Use of uninitialized value in eval "string" ... warning would be printed (if you had warnings enabled, which, as a righteous Monk, you always have :).

    Give a man a fish:  <%-{-{-{-<