SPUG: A dereferencing paradox?

Jeremy Devenport jeremy at weezel.com
Fri Sep 29 00:25:29 CDT 2000


Here's my quick dissection:

1. The regular expression /$_{cuisine}/i actually gets compiled as //.
That's a regular expression that matches everything. This happens because
"$_{cuisine}" is an empty string, why? Because %_ does not have a value
matching the key "cuisine". I verified this using "use re 'debug'" under
perl 5.6.0.

2. Changing it to $$_{cuisine} doesn't work because it shouldn't.
Substituting in the actual values gives us "'Asian' =~ /Asian Thai Chinese
Japanese/i". I think we can all see that 'Asian' does not contain the string
'Asian Thai Chinese Japanese'.

3. use strict and -w, not just a good idea... well actually it is just a
good idea. But the take-away from this email is "use re 'debug'" rules, does
this (or an equivilant) exist on earlier versions than 5.6.0?

I think it would be interesting to what kind of program other people on this
list would use to solve this problem. Any takers?

Jeremy

-----Original Message-----
From: owner-spug-list at pm.org [mailto:owner-spug-list at pm.org]On Behalf Of
Richard Anderson
Sent: Thursday, September 28, 2000 9:33 PM
To: spug-list at pm.org
Subject: SPUG: A dereferencing paradox?


As the group pointed out during my presentation at the last SPUG meeting,
the code in the following grep block looks wrong:

#! /usr/local/bin/perl
@database = ( { name      => 'Wild Ginger', city      => 'Seattle',
                cuisine   => 'Asian Thai Chinese Japanese',
                rating    => 4, payment   => 'MC VISA AMEX', }
            );
%query = ( cuisine => 'Asian', );
@res = find_restaurant(\@database, \%query);
print "$res[0]{name}\n";

sub find_restaurant ($$) {
   use strict;
   my ($database, $query) = @_;
   return grep {
         $$query{city} ? lc($$query{city}) eq lc($_{city}) : 1 and
         $$query{cuisine} ? $$query{cuisine} =~ /$_{cuisine}/i : 1 and
         $$query{min_rating} ? $_{rating} >= $$query{min_rating} : 1 and
         $$query{max_rating} ? $_{rating} <= $$query{max_rating} : 1 and
         $$query{payment} ? $$query{payment} =~ /$_{payment}/i : 1
      } @$database;
}

In the subroutine, $database is a reference to an array of references to
anonymous hashes (whew!).  In the grep statement, the $_ variable should be
set to a reference to a hash.  So shouldn't I be using $$_{key} instead of
$_{key}?

But when I run the above code, it works:
./restaurant_search.pl
Wild Ginger

If I replace $_ with $$_ within the grep block, I get a newline only:
./restaurant_search2.pl

Any explanations?

Richard.Anderson at raycosoft.com
www.zipcon.net/~starfire/home (personal)
www.raycosoft.com (corporate)


 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
  Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/




 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     POST TO: spug-list at pm.org       PROBLEMS: owner-spug-list at pm.org
      Subscriptions; Email to majordomo at pm.org:  ACTION  LIST  EMAIL
  Replace ACTION by subscribe or unsubscribe, EMAIL by your Email-address
 For daily traffic, use spug-list for LIST ;  for weekly, spug-list-digest
  Seattle Perl Users Group (SPUG) Home Page: http://www.halcyon.com/spug/





More information about the spug-list mailing list