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: <%-{-{-{-<
|