I recently have found two uses for eval which I thought some Monks may find useful in similar circumstances.
One is concerned with sorting the other with setting characteristics of cells in a table matrix.

Sorting
I often have data that can be seen in a table of a spreadsheet.
I store the data in a hash which has the structure $hs{$row}{$header} = value. In this $row is the row down the spreadsheet and $header is the name I give to the data in each column.
The simplest form of $header names is A B C etc as seen in a spreadsheet but I always have the first row with actual data names.
When I show this data in an application I want to
1. be able to choose which columns to sort on
2. be able to sort on numeric or text data
3. be able to sort from smallest to largest or smallest to largest.
The Perl below shows the ‘sort’ for the hash, given as a reference as $ref_spv to the sub, when
there are three data columns called Symbol, Sel120 and Sel119 which need to be sorted in that order
* Symbol and Sel120 are numeric – Sel119 is text
* Symbol and Sel119 are to be sorted upwards – Sel120 is to be sorted downwards.
The array @$ref_new_order contains a list of the sorted rows.
foreach $jrow (sort $ref_spv->{$a}->{Symbol} <=> $ref_spv->{$b}->{Symbol} || $ref_spv->{$b}->{Sel120} <=> $ref_spv->{$a}->{Sel120} || $ref_spv->{$a}->{Sel119} cmp $ref_spv->{$b}->{Sel119} } keys %$ref_spv) { push(@$ref_new_order, $jrow); }
It would be complicated (if not impractical)to write Perl code that allowed all the possibilities required when for example different columns were to be sorted.
However, it is relatively easy to write the Perl ‘sort’ string that defines the sort. In this case it is
$ref_spv->{$a}->{Symbol} <=> $ref_spv->{$b}->{Symbol} || $ref_spv->{$b}->{Sel120} <=> $ref_spv->{$a}->{Sel120} || $ref_spv->{$a}->{Sel119} cmp $ref_spv->{$b}->{Sel119}
The hash is then sorted by the Perl
foreach $jrow (sort { eval($sort_str); } keys %$ref_spv) { (@$ref_new_order
where $sort_str is the Perl ‘sort’ string.

Tablematrix cell characteristics.
The Tablematrix is a highly configurable widget that is a two dimensional table similar to a table in Excel.
Each cell in the table can have its own characteristics similar to individual widgets such as Entry boxes.
Therefore the background and foreground colours, the font and other things can be defined.
The cell definition is carried using a tag. When a tag is applied to a cell, all the characteristics set by other tags are overwritten.
Using a tag is a 2 stage process where the tag is defined and the defined tag is applied to one or more cells.
The tag is defined with Perl typically like
$t->tagConfigure($tag_name, -state => 'disabled', -bg => 'black');
In this case The name of the tag is stored in $tag_name This tag defines a condition where the cell will be disabled and the background colour is black.
The tag is applied with Perl typically like
$t->tagCell($tag_name, $cell_index);
The tag defined as $tag_name is applied to the cell with the ‘index stored in $cell_index. The cell index has the form row,column. Therefore an index of 2,3 refer to the cell row of 2 and column of 3.
I found that I wanted to:
1. set rows to a specific thing – for example background colour which differ from row to row;
2. set some columns to have a specific font;
3. override the general row and columns settings for individual cells.
I was working with tables that had around 20,000 cells. Therefore it would have been impractical to write individual tag definition and application Perl lines.
However, it was possible to build up and store the definition of the tags for all these cells and then apply them.
The stored definition, for example -state => 'disabled', -bg => 'black' was defined using eval as shown next.
$t->tagConfigure($tag_name, eval($tag_string));
where $tag_string was set to -state => 'disabled', -bg => 'black'
The tag was applied in exactly the same way.

Replies are listed 'Best First'.
Re: Uses of eval (sorting and tablematrix tags)
by salva (Canon) on Aug 30, 2011 at 10:44 UTC
    Running the eval inside the comparison function is pretty inefficient. A better aproach is to compile $sort_str into a sub and call it from the comparison block or just wrap the sort also inside the eval:
    foreach $jrow (eval "sort { $sort_str } keys %\$ref_spv") {...}

    Besides that, for that particular task you can use Sort::Maker or Sort::Key that create efficient sorting functions from a description of the keys. For example:

    my $sorter = Sort::Key::multikeysorter(sub { @{$ref_spv->{$_}}{qw(Symb +ol Sel120 Sel119)} }, qw(String String -Int)) foreach $jrow ($sorter->(keys %$ref_spv)) { ... }
      Thanks for those comments. I did not know you could improve things in the way you suggested. I may well be able to use that elsewhere.
      Also it was good to hear of the sort modules that I have to come across before now.