2

I am currently reading Intermediate Perl from O'Reilly and am attempting to to do one of the exercises. I am new to references in Perl, so I hope that I am not misunderstanding something and coding this exercise incorrectly.

However, I have tried to debug this code and I am not able to come to a conclusion as to how the line with the smart matching is failing every time. From what I understand @array ~~ $scalar should return true if the string-wise scalar value is found in the @array.

Below is my code:

#!/usr/bin/perl -w
use 5.010;

my @rick  = qw(shirt shotgun knife crossbow water);
my @shane = qw(ball jumprope thumbtacks crossbow water);
my @dale  = qw(notebook shotgun pistol pocketprotector);
my %all   = (
    Rick  => \@rick,
    Shane => \@shane,
    Dale  => \@dale,
);

check_items_for_all(\%all);

sub check_items_for_all {
    my $all = shift;
    foreach $person (keys %$all) {
        #print("$person\n");
        $items = $all->{$person};
        #print("@$items");
        check_required_items($person, $items);
    }
}

sub check_required_items {
    my $who      = shift;                #persons name
    my $items    = shift;                #reference to items array
    my @required = qw(water crossbow);
    print(
        "Analyzing $who who has the following items: @$items. Item being compared is $item \n"
    );
    foreach $item (@required) {
        unless (@$items ~~ $item) {
            print "Item $item not found on $who!\n";
        }
    }
}
ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Burzum619
  • 143
  • 3
  • 13
  • Also, the example in the book uses the grep perl function rather than smart matching, but I would still like to figure out why my code is not behaving appropriately. – Burzum619 Aug 06 '12 at 18:22
  • 1
    I'd personally avoid smart match as a general rule. There are a few cases where it might be a handy shorthand, but many of the matching cases are esoteric and have weird pitfalls. The current Perl Pumpking, Ricardo Signes, has recommended against their use in all versions of Perl where it is currently available. – zostay Aug 06 '12 at 18:46
  • @zostay Of course there are pitfalls (Perl is one big minefield ;-)), but once you learn all the little specialities and surprises, I think they are a godsend. And they short-circuit, contrary to `grep`. And they work without you having to figure out the type. And we can use `when`! Just to express a counterposition. Tim Toady. – amon Aug 06 '12 at 19:22
  • @amon, I wouldn't call Perl a minefield, at least no more than any other language. You are more than welcome to use smart match and I didn't say never use, I said avoid it as a general rule. I have used it in a few cases. It's like an oddly designed Leatherman. It has some interesting uses, especially in a pinch, but you probably end up wanting a regular screw driver or real pair of pliers or a pair of actual scissors when you have the time to go fetch them. – zostay Aug 06 '12 at 20:23
  • 2
    related: http://stackoverflow.com/questions/5279917/why-doesnt-this-smart-match-work – daxim Aug 06 '12 at 22:09
  • Which exercise and which edition of the book? – brian d foy Aug 06 '12 at 23:59

1 Answers1

4

If you reverse the match it will work:

$item ~~ @$items

or

$item ~~ $items  # Smart-matching works with references too.

PS: get used to adding use strict; to the start of your program. It will point you to a few mistakes in your code :)

amon
  • 57,091
  • 2
  • 89
  • 149
pavel
  • 3,488
  • 1
  • 20
  • 20
  • Thanks @pavel! Other than for clarity, why would I want to avoid using smart matching as a general rule? What's wrong with it? – Burzum619 Aug 06 '12 at 19:46
  • when used with care, I'm all for smart matches. – pavel Aug 06 '12 at 19:49
  • Burzum619, see http://programmers.stackexchange.com/questions/122151/why-is-perls-smart-match-operator-considered-broken and a better implementation [Smart::Match](http://p3rl.org/Smart::Match). – daxim Aug 06 '12 at 22:11