arraysperlsolarisarrdata-dumper

Can't use string as an ARRAY ref while strict refs in use


Getting an error when I attempt to dump out part of a multi dimensional hash array. Perl spits out

Can't use string ("somedata") as an ARRAY ref while "strict refs" in use at ./myscript.pl

I have tried multiple ways to access part of the array I want to see but I always get an error. I've used Dumper to see the entire array and it looks fine.

#!/usr/bin/perl

use strict;
use warnings;

use Data::Dumper qw(Dumper);
use String::Util qw(trim);

my %arrHosts;

open(my $filehdl, "<textfile.txt") || die "Cannot open or find file textfile.txt: $!\n";

while( my $strInputline = <$filehdl> ) {
  chomp($strInputline);
  my ($strHostname,$strOS,$strVer,$strEnv) = split(/:/, $strInputline);
  $strOS = lc($strOS);
  $strVer = trim($strVer);
  $strEnv = trim($strEnv);
  $strOS = trim($strOS);
  $arrHosts{$strOS}{$strVer}{$strEnv} = $strHostname;
}

# If you want to see the entire database, remove the # in front of Dumper
print Dumper \%arrHosts;

foreach my $machine (@{$arrHosts{solaris}{10}{DEV}}) {
  print "$machine\n";
}

close($filehdl);

The data is in the form machine:OS:OS version:Environment

For example

bigserver:solaris:11:PROD
smallerserver:solaris:11:DEV

I want to print out only the servers that are solaris, version 11, in DEV. Using hashes seems the easiest way to store the data but alas, Perl barfs when attempting to print out only a portion of it. Dumper works great but I don't want to see everything. Where did I go wrong??


Solution

  • You have the following:

    $arrHosts{$strOS}{$strVer}{$strEnv} = $strHostname;
    

    That means the following contains a string:

    $arrHosts{solaris}{10}{DEV}
    

    You are treating it as if it contains a reference to an array. To group the hosts by OS+ver+env, replace

    $arrHosts{$strOS}{$strVer}{$strEnv} = $strHostname;
    

    with

    push @{ $arrHosts{$strOS}{$strVer}{$strEnv} }, $strHostname;
    

    Iterating over @{ $arrHosts{solaris}{10}{DEV} } will then make sense.