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

Hello,
I am still new to perl. I am having difficulty understanding why the first element of @toy is the only one being searched for. Why dont the 2nd,3rd and 4th elements? I am not sure how to increment the other elements.
Any Ideas
Thanks
@toy = ("Jan","Feb","Mar","Apr"); &search_database(@toy); sub search_database{ my $search_for = $_[0]; open(DB, $database) or die "Error opening file: $!\n"; while(<DB>){ if($search_field =~ /all/i){ if(/$search_for/oi){push @results, $_}; } else { ($key,@field_vals) = split(/\::/, $_); if($field_vals[$search_field] =~ /$toy/oi){push @results, $_}; } # End of else. } # End of while. close (DB); } # End of search_database subroutine...

Replies are listed 'Best First'.
Re: Need help with toy array. THX
by Zaxo (Archbishop) on Sep 16, 2002 at 05:44 UTC

    If you add these lines at the start, you will find lots of useful messages:

    use warnings; # needs 5.6.0 or newer, # $^W = 1; # for older use strict;

    The $search_for variable is only ever set to "Jan" because you assign it that way in my $search_for = $_[0];. I think you want to do something like this:

    sub search_database { my $database = shift; my @search_for = map {qr/$_/i} @_; my @results; open(DB, $database) or die 'Error opening file: ', $!; while (<DB>) { my @record = split /::/; push @results, [@record] if grep { $record[5] # or whichever =~ /$_/i; # /o taken care of by qr } @search_for; } close DB or die $!; \@results; }
    That removes the $search_field conditions which are badly set up and are confusing the issue. The search now is restricted to just the field where a date should appear, avoiding confusion with "Janice", "Martin", and "taproot". The function now returns a reference to the @results array instead of writing to one in a larger scope. The arguments are changed to include the name of the $database file. The caller gets all fields, and can index the desired ones.

    After Compline,
    Zaxo

      It should probably be mentioned that since the sub now returns a reference, you'll need to call the function with something like:
      my $resultsRef = search_database($dbName,@toy); foreach my $result (@$resultsRef) { ... }
      Since an array reference is returned, you need to use '@$' to dereference the array.

      -C
      print(map(lc(chr),split(6,qw/99672682673683684689632658645641610607/)));
      Agreed, Zaxo++. It should also be noted (as cal indicates that he is still new to Perl) for posterity's sake that passing arrays by reference is usually a Good Idea™. It eliminates the semantic clutter that often comes along with Perl's squishing the parameter list into one big list, and it is always faster to pass arrays by reference when passing anything but the most trivially sized arrays (which becomes crucial when dealing with Biggie-sized arrays on enterprise systems).
Re: Need help with toy array. THX
by kabel (Chaplain) on Sep 16, 2002 at 05:33 UTC
    if you "use warnings" you should get a message that $toy is used only once. the array @toy is (because of the implementation) (nearly) complete separated from the scalar $toy. a use strict should blow up your code. your parameter passing is logically wrong. you call it with a list and then you take only the first parameter out of it! better: my (@search_for) = @_;. now @search_for has the same entries as @toy. $search_field is nowhere defined. ? for the regex: you could try my $search_for_regex = join "|", @toys; and then search for $search_for_regex. ;) the | is the alternation operator in a regex.