in reply to Changing variable names in a loop

If you want a parser that you don't have to change when you change your set of input criteria, you can do something like the following:

use strict; use warnings; use Data::Dumper; my %config = map { /^((?:inc|exc)_\w+)=(.*)$/ } <DATA>; print Dumper(\%config); __DATA__ inc_albums= a list of albums to include inc_genres= a list of genres to include inc_artists= a list of artists to include inc_songs= a list of songs to include inc_year= a list of years to include exc_albums= a list of albums to exclude exc_genres= a list of genres to exclude exc_artists= a list of artists to exclude exc_songs= a list of songs to exclude exc_year= a list of years to exclude

Which gives:

$VAR1 = { 'inc_genres' => ' a list of genres to include', 'inc_year' => ' a list of years to include', 'exc_albums' => ' a list of albums to exclude', 'inc_albums' => ' a list of albums to include', 'exc_year' => ' a list of years to exclude', 'exc_songs' => ' a list of songs to exclude', 'inc_artists' => ' a list of artists to include', 'inc_songs' => ' a list of songs to include', 'exc_artists' => ' a list of artists to exclude', 'exc_genres' => ' a list of genres to exclude' };

Replies are listed 'Best First'.
Re^2: Changing variable names in a loop
by Mad_Mac (Beadle) on Oct 16, 2010 at 09:45 UTC

    NICE! That's even simpler than what I was expecting. :-D

    Thanks for the help.

    So, the values of the hash are a list separated by semicolons (just because I picked semicolons for the delimiter in my input text file). I need to put the list of values into an array, so I can use them to build my SQL statements. Sort of like this:

    # Maybe I can do this as part of the original parsing? # Or maybe I can loop over the %config hash and convert # the scalar values to an array, and put a reference # to that array back into the hash? @inc_albums=split(/; /, $inc_albums) unless $inc_albums=~/^\s$/; @inc_genres=split(/; /, $inc_genres) unless $inc_genres=~/^\s$/; @inc_artists=split(/; /, $inc_artists) unless $inc_artists=~/^\s$/; @inc_songs=split(/; /, $inc_songs) unless $inc_songs=~/^\s$/; @exc_albums=split(/; /, $exc_albums) unless $exc_albums=~/^\s$/; @exc_genres=split(/; /, $exc_genres) unless $exc_genres=~/^\s$/; @exc_artists=split(/; /, $exc_artists) unless $exc_artists=~/^\s$/; @exc_songs=split(/; /, $exc_songs) unless $exc_songs=~/^\s$/; my $i_albumcriteria=q{(Songs.Album LIKE '%'||}.join(q{||'%' OR Songs.A +lbum LIKE '%'||},map {"?"} @inc_albums).q{||'%')} unless (scalar(@inc +_albums)==0) ; my $i_artistcriteria=q{(Songs.Artist LIKE '%'||}.join(q{||'%' OR Songs +.Artist LIKE '%'||},map {"?"} @inc_artists).q{||'%')} unless (scalar( +@inc_artists)==0); my $i_songcriteria=q{(Songs.SongTitle LIKE '%'||}.join(q{||'%' OR Song +s.SongTitle LIKE '%'||},map {"?"} @inc_songs).q{||'%')} unless (scala +r(@inc_songs)==0); my $i_genrecriteria=q{(Songs.Genre LIKE '%'||}.join(q{||'%' OR Songs.G +enre LIKE '%'||},map {"?"} @inc_genres).q{||'%')} unless (scalar(@inc +_genres)==0); my $i_ratingcriteria=qq{Songs.Rating $inc_ratings} unless length($inc_ +ratings)<2; my $i_datecriteria=qq{Songs.Year $inc_year} unless length($inc_year)<2 +;

    I'm now trying to work out how to either do this while I'm parsing the input text the first time around, or by looping over the %confighash recommended by ig. I could use a little bit more help on this.

    EDIT

    I think I got it ...

    foreach my $k (keys %config) { $config{$k}=[split(/; /, $config{$k})] unless $config{$k}=~/^\s$/; }

    Thanks again for the help.

      You could do something like:

      use strict; use warnings; use Data::Dumper; my %config = map { /^((?:inc|exc)_\w+)=(.*)$/; ( $1, [ split(/\s*;\s*/,$2) ] ) } <DATA>; print Dumper(\%config); __DATA__ inc_albums=a; list; of; albums; to; include inc_genres=a; list; of; genres; to; include inc_artists=a; list; of; artists; to; include inc_songs=a; list; of; songs; to; include inc_year=a; list; of; years; to; include exc_albums=a; list; of; albums; to; exclude exc_genres=a; list; of; genres; to; exclude exc_artists=a; list; of; artists; to; exclude exc_songs=a; list; of; songs; to; exclude exc_year=a; list; of; years; to; exclude

      But I find such code too cryptic and would probably do it more like the following myself: