views:

89

answers:

3

So, building off a question about string matching (this thread), I am working on implementing that info in solution 3 into a working solution to the problem I am working on.

However, I am getting errors, specifically about this line of the below function:

next if @$args->{search_in} !~ /@$cur[1]/;

syntax error at ./db_index.pl line 16, near "next "

My question as a perl newbie is what am I doing wrong here?

sub search_for_key
{
    my ($args) = @_;

    foreach $row(@{$args->{search_ary}}){
        print "@$row[0] : @$row[1]\n";
    }

    my $thiskey = NULL;
    foreach $cur (@{$args->{search_ary}}){
        print "\n" . @$cur[1] . "\n"
        next if @$args->{search_in} !~ /@$cur[1]/;
        $thiskey = @$cur[0];
        last;
    }
    return $thiskey;    
}
+6  A: 

You left off the semicolon at the end of the previous line. That's what caused the syntax error, anyway. I think you're also misusing $args, but it's hard to be sure about that without knowing how you're calling this function.

cjm
@cjm Hooray for dumb mistakes. Thanks. Didn't see that one.
Ben Dauphinee
+1  A: 

Side note, are you sure you can't just use a hash for what you're doing? It seems awfully complicated do do something so simple:

my %hash = ( 
     key1 => 'value1',
     key2 => 'value2',
);

exists $hash{$search_in};   # true/false.
my $result = $hash{$search_in}; # returns 'value1' when $search_in is 'key1'

Or if you need to search by value:

my %flip = reverse %hash;
$result = $flip{$search_in};

And if you really need a regex key ( or value ) lookup:

 sub string_match {
        my ($lookup_hash, $key ) = @_;
        for my $hash_key ( %{ $lookup_hash } ){ 
            return $hash_key if $key =~ $lookup_hash->{$hash_key};
        }
        return; # not found.
 }
 my $k = string_match({
           'whitespace at end' =>  qr/\s+$/,
           'whitespace at start' => qr/^\s+/,
 }, "Some Garbage string     ");  # k == whitespace at end 
Kent Fredric
@Kent This array is coming from a database select (dbi: $ref = $sth->fetchall_arrayref;). Would I still be able to use this as a hash?
Ben Dauphinee
@Ben , my ( %hash) = map { @{ $_ } } @{ $sth->fetchall_arrayref } # I guess so. But it may be less efficient, depending on how many lookups you're doing on the data. The smart thing to do would be modify your statement search to return the right data instead =).
Kent Fredric
+2  A: 

There are several issues here.

  1. Are you adding use strict; and use warnings; at the top of your script before you do anything else? You only posted the sub, but it is clear that you are not using these.

  2. What is NULL? (strict will not let you use bare-words...) Be sure to read What is Truth in Perl? The more Perly way is to deal with "truth" or "false" is defined / undef or exists or specifically test for a value chosen as a convention.

  3. Missing ; after print "\n" . @$cur[1] . "\n"

  4. Your data structures seem way too complicated. From what I can tell, you are passing a reference to a hash of arrays, true? Why your data structures get really obscure, back up and look at what you are trying to do...

  5. Perl gives you plenty of way to shoot yourself in the foot. It is not strictly typed and you will do yourself (and your readers) a favor by naming references as a derivative of what they refer to. So instead of $args use $ref2HoArefs for example.

drewk
+1, but almost -1 for the obscene hungarian notation. :/
Kent Fredric
@Kent: What Windows 1.0 - 3.0 missed in engineering, Charles Simonyi made up in attitude! Course he got to go into space on private Russian rockets while we sit here using his naming convention!
drewk
I concur, the notation proposed in 5. is awful. A variable should be named after what it does (the purpose), not the type of data it contains. Casual inspection (dumping) will reveal the data structure of complex types, and simple types are already recognisable from their sigil. However, you cannot get the intention or purpose from dumping; this is the programmer's responsibility. Therefore, `$args` is in fact a better choice than `$ref…`.
daxim
@daxim: I prefer to know what intention of the reference instead of the intention of the use. Without comment or naming convention it is impossible to know what the intended reference is and if the sigil is actually correct. The intention of use is more clear here than the reference. If you look at http://perldoc.perl.org/perlreftut.html, this is also the suggested format...
drewk
[The author of perlreftut](http://perl.plover.com) writes: »The perlreftut manual does not "suggest" that variable names encode the type of the variable. The document is completely silent on all matters of variable naming, because its purpose is to provide an introduction to Perl reference syntax, not to advise on matters of variable naming. Citing it as an authority on matters of proper variable naming is as futile as citing it as an authority on proper indentation style or any other style issue.«
daxim