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

Trying out an exercise that uses dereferencing Below is code and error

#! /usr/bin/perl use v5.16.3; use strict; use warnings; ## 7/31/19 ## program uses derefence to simplify subroutine from previous program sub check_required_items { my ($who, $items) = @_; my %whos_items = map { $_, 1 } @$items; # the rest are the person +'s items my @required = qw(preserver sunscreen water_bottle jacket); for my $item (@required) { unless ( $whos_items{$item} ) { # not found in list print "$who is missing $item, \n"; } } } my @gilligan = qw(red_shirt hat lucky_socks water_bottle); check_required_items('gilligan', @gilligan); my @skipper = qw(blue_shirt hat jacket preserver sunscreen); my @professor = qw(sunscreen water_bottle slide_rule batteries radi +o); check_required_items('skipper', @skipper); check_required_items('professor', @professor); Can't use string ("red_shirt") as an ARRAY ref while "strict refs" in +use at ./Page_42 line 12.

TIA The Catfish

Replies are listed 'Best First'.
Re: Using Dereferencing
by Fletch (Bishop) on Jul 31, 2019 at 17:50 UTC

    Presuming your question is the implied "Why am I getting this errror?" . . .

    When you call check_required_items( 'foo', @bar ) the array @bar is expanded out into the contained items. The sub however expects it to be a reference to an array and it's telling you it can't use the string "red_shirt" as a reference to the array. You want to use a backslash in front of the array name to pass a reference to it: check_required_items( 'gilligan', \@gilligan ). See perlreftut for more details.

    The cake is a lie.
    The cake is a lie.
    The cake is a lie.

Re: Using Dereferencing
by soonix (Chancellor) on Jul 31, 2019 at 18:19 UTC
    my ($who, $items) = @_;
    You seem to expect an array ref in $items, actually, it will be just the second argument (first item of e.g. @gilligan), the rest will be discarded. Why not
    my ($who, @items) = @_;
    then you could map ... @items without needing to dereference.
Re: Using Dereferencing
by BillKSmith (Monsignor) on Jul 31, 2019 at 18:26 UTC
    Your use of the name Page_42 number suggests that you are using the book "Intermediate Perl". You can find a correct example of your function call on page 41. You omitted the "take a reference to" operator (also known as the 'blackslash" operator in Perl documentation perlref). It is explained on pages 38 and 39.
    Bill
Re: Using Dereferencing
by AnomalousMonk (Archbishop) on Jul 31, 2019 at 19:25 UTC

    Others have pinpointed the problem of not taking and passing an array reference. Just for grins, run the OPed code without strictures asserted, e.g.,
        # use v5.16.3;
        # use strict;
    (the  use v5.16.3; statement has to be commented out because IIRC use-ing Perl version 5.16+ automatically asserts strictures), and see what happens. Note that you can still assert warnings. Is there necessarily any hint that something might be going wrong?


    Give a man a fish:  <%-{-{-{-<

Re: Using Dereferencing
by TieUpYourCamel (Scribe) on Dec 12, 2019 at 21:28 UTC
    I think the following is cleaner. There's no need to create a separate array. Just shift off the name and map the rest.
    my $who = shift; my %whos_items = map { $_, 1 } @_; # the rest are the person's items